Solved QDialog doesn't close
-
@gabor53 you no need to do that for use QMessageBox.
The easy could be (for me) to call messageBox from conditionnal error test, and use the buttons allready provided (if need to use/add button, it steal easy to):bool error(true); QString my_datas("test"); if(error) QMessageBox::warning(this, tr("my title window"), tr("my error message: %1").arg(my_datas));
also, QMessageBox (like all Dialog box by default) will send back a int answer type object. So "switch()" C++ function should catch answer back after close.
And also, you can give name of your buttons directly from warning member function, et the end...). Look at API for QMessageBox, there is some examples.
Also, if your code is outside of messageBox (that seems to be the fact in your code), first, your condition will be read after the messagebox closed... if you want to read things before, so you have to put the code inside (so inherit QMessageBox for that). or use "QObject::connect" method for pass signal from QMEssageBox to a slot who will do what you want other.
But if it is just for close QMEssageBox, you absolutly not need all of this you try to do, but only call QMessageBox as i show you, it will have OK button allready inside, and it will work directly out of the "QMessageBox"... if not, there is a problem.Also... if you want to cath QMessageBox buttons events, you have to first declare a pointer on QMessageBox for use it from a QObject::connect (and your class has to have QOBJECT macro inside declaration somewhere for ba able to use connections).
example:QMessageBox *mgx; mgx = new QMessageBox(this); mgx.warning(this, tr("my title window"), tr("my text")); mgx.setStyleSheet("QLabel{color: green; font-size: 16;} QWidget{background-color: white;}"); // all the CSS style you want to give to your content... should go there in CSS style code with some features like wich object should have wich CSS "paint" connect(mgx, SIGNAL(buttonClicked(QAbstractButton), this, SLOT(on_OK_mgx_clicked(QAbstractButton)); mgx->open();
also, you have to create the function member declared as private (or public) slot, and then define it in cpp file (void on_OK_mgx_clicked(QAbstractButton button); in header file, then define it in source file linked.
that way you will catch button clicked returned by QAbstractButton object from clecked event in QMessageBox. But i think it is not what you are searching for... this is more complictae than use default mechanism for print a message with a close button.If you want more features, try first like that, play around after read the API on that, and ask more precisely what you try to do with QMessageBox (what is the finality).
http://doc.qt.io/qt-4.8/qmessagebox.html#buttonClicked
Hope that help. -
@jerome_isAviable
Thanks. The thing is I want to close the dialog called Additem that called QMessageBox.
QMessageBox closes wonderfully but any attempt to close Additem is disregarded. -
Are you sure
msgBox.clickedButton()
isn't NULL? This might happen if the message box was dismissed with a key. -
@kshegunov
How can I check? -
@gabor53
As you'd check any other pointer:QAbstractButton * clickedButton = msgBox.clickedButton(); if (!clickedButton) { qDebug() << "Well, we are out of luck. " << "The message box was dismissed with a key so this check: " << "msgBox.clickedButton () == OKButton is meaningless" << endl; }
-
@kshegunov
I did the following (before you posted your last message):if(msgBox.clickedButton () == NULL) { qDebug() << "ClickButton is null"; } else { qDebug() << "ClickButton is NOT null."; }
According to this code the clickedButton() is not NULL.
-
@gabor53
Okay then, going to the basics. Can you confirm that thethis->reject()
is called? That is, do you get the debug message"OK was clicked."
.
Another thing I just noticed:
Why do you have an overload forreject()
? This is usually not necessary, can you show that function and its declaration?Kind regards.
-
@gabor53 ok, well i understand better.
so you need to use it like that:QMessageBox mgx; int answer = mgx.warning(this, "my fix title", "my fix text"); if(answer == Qt::accept()) this->close();
that's all.
or with a question to validate:
int answer = QMessageBox::question( this, tr("Question tag..."), tr("read the error:/n%1 ").arg(error_string), tr("Close"), tr("Not close")); if(answer == 1) this->close();
and... don't forget to tell us (for share for other who will have same problem) finally what solution you choosed and worked for you and make the subject as "resolved" (said thank you for helpers time is also a nice option i like sometimes to read or write...).
thank you. -
@jerome_isAviable
I implemented this:{ qDebug() <<"Error inserting into the main db!" << querys.lastError (); QMessageBox::warning (this,"Add to Database Warning","<b><font size='16' color='red'>Error 1002: The Friend was not added to the database."); } else { qDebug() << "Entered FunctAdd OK loop."; QMessageBox msgBox; int answer = msgBox.information (this, tr("Confirmation"), tr("<b><font size = '16' color = 'green'>The Friend was added to the database. To add more press CTRL A."), QMessageBox::Close); if(answer == QMessageBox::Close) { this->close(); } } db.close (); } }
There are no error messages, and it enters the right loop
(displays " qDebug() << "Entered FunctAdd OK loop.";)
but the Additem dialog is still not closed. I have no idea why. -
@gabor53 try to use default message box button (not add QMessageBox::Close in information)
and use condition if(answer == 0) instead.
But... the principe is that, if your messagebox is modal, then the message box is waiting for you push button "OK" before the code ga ahead... right ?
so finally, condition serve nothing (there is only one button... condition serve for what ?).
finaly, just don't use condition but this->close() after QMessageBox::information.
Also, no need to declare QMessageBox mgx in this situation, directly call QMessageBox::information(....);
declare a variable for contain an object (QMessageBox or other) serve for add stuff/options and use it in other situation you not need here.so the code you need should also be:
QMessageBox::information (this, tr("Confirmation"), tr("<b><font size = '16' color = 'green'>The Friend was added to the database. To add more press CTRL A.")); this->close();
as soon as possible: do it simple, do it easy.
on my codes (if i well understand what you are doing), i use a QMessageBox::question for ask if the user want to create an other one new object, if he want i clear entries or not for that or if it is finish. Then from there, i catch the answer (who is the number of button pushed) for call action like close or not, and function for delete entries of this dialog box or not. So when i'm waiting for know what the user want to do next, i ask him what him want. (i not said it is a good idea... there is many... but... it is an idea).
Did you try the code i share with you with QMessageBox::question ? this one works sure.
also, for see what int answer give you, you could try to add a "qDebug() << answer;" The retrurn depend of the function you call and the button you push. This would help you to see what to catch in condition for do what you want (i do like that when i'm not sure or when something not works like i would like...). -
@jerome_isAviable
Thank you. I really understand how this work. I guess the problem is thatthis->close()
doesn't work no matter how I write QMessageBox. It doesn't even work, when there is no QMessageBox.
-
@gabor53 said:
I guess the problem is that
this->close()
doesn't work no matter how I write QMessageBox. It doesn't even work, when there is no QMessageBox.Which means there's no problem with
QMessageBox
but with the rest of your code.void Additem::close() { qDebug() << "Close was called"; Additem::reject (); }
If close is properly called then you'd see "Close was called" in the debug window. If you don't see that, then
close()
isn't called. Use the debugger, put a breakpoint at the line wherereject()
is supposed to be called, if you don't hit the breakpoint, then you have your answer - the code is not executed at all.Another thing,
Additem::reject();
is a pretty strange way of calling members. Why are you using the fully qualified name to call the method, do you have areject()
override? -
@kshegunov
I see the "Close was called." message and it goes to reject(). But nothing happens. -
@gabor53
You did not answer my question though.Additem::reject(); is a pretty strange way of calling members. Why are you using the fully qualified name to call the method, do you have a reject() override?
-
@kshegunov
Sorry. Sorry. I don't have a reject() override. I used the fully qualified name because I tried to use the name different ways just in case one version works. But none of these work:reject() this->reject() Additem::reject()
-
That's unusual. Please provide the full class declaration of
Additem
and how you show the dialog. -
@kshegunov
Additem declaration (the whole Additem.h):#ifndef ADDITEM_H #define ADDITEM_H #include "review.h" #include "mainwindow.h" #include <QBoxLayout> #include <QDialogButtonBox> #include <QCalendarWidget> #include <QComboBox> #include <QCoreApplication> #include <QDate> #include <QDebug> #include <QDialog> #include <QDialogButtonBox> #include <QDir> #include <QDirModel> #include <QFileSystemModel> #include <QFileDialog> #include <QFlags> #include <QFocusEvent> #include <QFont> #include <QFormLayout> #include <QGridLayout> #include <QIODevice> #include <QLabel> #include <QLineEdit> #include <QListView> #include <QMainWindow> #include <QMessageBox> #include <QPushButton> #include <QScrollArea> #include <QSize> #include <QSizePolicy> #include <QSqlDatabase> #include <QSqlError> #include <QSqlQuery> #include <QStackedLayout> #include <QString> #include <QStringList> #include <QTextEdit> #include <QtCore> #include <QtGlobal> #include <QToolTip> #include <QTreeView> #include <QWidget> #include <QWindow> namespace Ui { class Additem; } class Additem : public QDialog { Q_OBJECT public: //db //Buttons QPushButton *SubmitButton = new QPushButton; QPushButton *Image_Button = new QPushButton("Browse"); QPushButton *Reset_Button = new QPushButton; //Functions void FunctAddtoDb(QString sIDr, QString namer, QString newWhatr, QString newMaterialr, QString newColorr, QString descriptionr, QString monthr, QString dayr, QString yearr, QString newSignedbyr, QString historyr, QString ager, QString notesr, QByteArray byteArrayr); void close(); void closeAdditem(); QString name; explicit Additem(QWidget *parent = 0); ~Additem(); private: Ui::Additem *ui; //Functions void Addcontent(); QString getDescription(); QString getHistory(); void prepAdd(); void clear(); //QLabel QLabel* title = new QLabel; QLabel *angry_image_Label = new QLabel; QLabel *incorrect_Label = new QLabel; QLabel *spacer1 = new QLabel; QLabel *Label_ID = new QLabel; QLabel *ID_Display = new QLabel; QLabel *Label_Name = new QLabel; QLabel *Label_What = new QLabel; QLabel *image_Label = new QLabel; QLabel *display_Label = new QLabel; QLabel *Material_Label = new QLabel; QLabel *color_Label = new QLabel; QLabel *descr_Label = new QLabel; QLabel *date_Label = new QLabel; QLabel *month_Label = new QLabel; QLabel *day_Label = new QLabel; QLabel *year_Label = new QLabel; QLabel *spacer2_Label = new QLabel; QLabel *spacer3_label = new QLabel; QLabel *signed_Label = new QLabel; QLabel *history_Label = new QLabel; QLabel *age_Label = new QLabel; QLabel *notes_Label = new QLabel; //Textedit QTextEdit * descr_TextEdit = new QTextEdit; QTextEdit *history_TextEdit = new QTextEdit; QTextEdit *notes_TextEdit = new QTextEdit; //Lineedit QLineEdit *age_LineEdit = new QLineEdit; //QCombobox QComboBox *What_Combo = new QComboBox(this); QComboBox *Material_Combo = new QComboBox; QComboBox *color_Combo = new QComboBox; QComboBox *month_Combo = new QComboBox; QComboBox *day_Combo = new QComboBox; QComboBox *year_Combo = new QComboBox; QComboBox *signedby_Combo = new QComboBox; //Layouts QHBoxLayout *name_Layout = new QHBoxLayout; QHBoxLayout *titleLayout = new QHBoxLayout; QHBoxLayout *button_Layout = new QHBoxLayout; QHBoxLayout *dateLayout = new QHBoxLayout; QVBoxLayout *mainLayout = new QVBoxLayout(this); QGridLayout *grid = new QGridLayout; //QString QString fileQstring = "C:/Programming/Projects/FolkFriends/db.db"; QSqlDatabase db; QString what; QString newWhat; QString fileName; QString material; QString newMaterial; QString color; QString newColor; QString description; QString si; QString sj; QString sk; QString month; QString day; QString year; QString Signedby; QString newSignedby; QString history; QString age; QString notes; QString submit_warning; QString warning_what; QString submitError; QString sID; QString sIDr; QStringList list; //Int int ItemID = 0; int LastID = 0; int revItemID = 0; int yeark; int r; //Other QLineEdit *LineEdit_Name = new QLineEdit; QByteArray inByteArray; QByteArray byteArray; private slots: void readAndValidate(); void addMonth(int); void resetAll(); void submit(); void getAge(); QString getNotes(); void addSignedby(int); void addDay(int); void addYear(int); void getMaterial(int); void processcombo(int); void addColor(int); QString findimage(); void closeAdd(); }; #endif // ADDITEM_H
This is the way I open it from mainwindow.cpp:
void MainWindow::on_actionAdd_Item_triggered() { Additem *mAddItem = new Additem; mAddItem->exec (); }
-
I couldn't spot anything that would cause this behavior. My advice is to strip down the code to the bare basics, and then add things in stages to isolate what is causing the problem.
-
@gabor53
please, check that your class is a real QDialog and not a inherited from a QWidget.
If it is a QDialog well inherited, and the member function close() is not overrided, then I don't know any reasons for the dialogbox (if it is a real QDialog) not close.eventually, do paste your code: header and source files of this QDialog box who doesn't want to close.
(use gist github or ix.io or wich you want for share this code, like that we can look at this closer) -
Thank you all. I started to rebuild things in hope that solves the problem.