int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDialog dlg;
dlg.exec();
return a.exec();
}
That's all my code, but when I close the window, The process isn't exit, it seems that drop in the loop a.exec()
.
Generally speaking, calling any exec is a bad idea, other than QCoreApplication::exec()
or QDrag::exec()
. The presence of exec()
and waitForXxx()
methods is an enticing trap for the unwary. Those methods are "easy" to use, but that ease comes at a price of hard to track bugs. Don't use them.
You should simply show the dialog:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMessageBox msg;
msg.setText("Hello");
msg.addButton(QMessageBox::Close);
msg.show();
return a.exec();
}
If you wish to wait for the dialog to be accepted or rejected, you should use the dialog's clickedButton
slot. QMessageBox
has a long-standing bug that makes the accepted
and rejected
signals useless :(
// https://github.com/KubaO/stackoverflown/tree/master/questions/messagebox-show-25545652
#include <QtGui>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#endif
#include <functional>
[...]
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QMessageBox msg;
msg.setText("Continue?");
msg.addButton(QMessageBox::Yes);
msg.addButton(QMessageBox::No);
auto onClick = [&msg]() {
auto role = msg.buttonRole(msg.clickedButton());
if (role == QMessageBox::NoRole)
QApplication::quit();
if (role == QMessageBox::YesRole) {
auto label = new QLabel("I'm running");
label->setAttribute(Qt::WA_DeleteOnClose);
label->show();
}
};
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
QObject::connect(&msg, &QMessageBox::buttonClicked, onClick);
#else
QObject::connect(&msg, SIGNAL(buttonClicked(QAbstractButton*)),
new FunctorSlot{onClick, &msg}, SLOT(call()));
#endif
msg.show();
return app.exec();
}
#include "main.moc"
For Qt 4, you need the following helper:
// Qt 4 only
struct FunctorSlot : public QObject {
Q_OBJECT
public:
std::function<void()> callable;
template <typename Fun>
FunctorSlot(Fun && fun, QObject * parent = {}) :
QObject{parent}, callable{std::forward<Fun>(fun)} {}
Q_SLOT void call() {
callable();
}
};
Possible solution:
QApplication a(argc, argv);
QDialog dlg;
QTimer::singleShot( &dlg, 0, SLOT(exec()) );
return a.exec();
It will work well. First - application event loop will be started. Then dialog event loop will be executed. After closing of dialog, both dialog and application loop will be finished. Application loop will be terminated automatically (by default), when last window is closed.
But, as noted by @thuga - there are no reason to call exec()
. It is enough to call show()
method.
来源:https://stackoverflow.com/questions/25545652/qdialog-exec-can-not-exit-process