我正在开发一个exec()的应用程序,它是另一个对话框。 这里的问题是在构造函数中执行庞大的任务持有exec()的UI。 一旦构造函数完成,它就会显示表单。
我的问题是如何同时显示表单和exec()构造函数。
这就是我现在这样做的方式,
Event2 ev2_obj(this);
if(Event1::Accepted == ev2_obj.exec())
{}
答案 0 :(得分:0)
如果没有一个不同的应用程序启动它自己的GUI,我不认为Qt允许你在调用exec()之前显示任何GUI。
正如其他人所建议的那样,考虑将庞大的任务从构造函数中移除。
答案 1 :(得分:0)
使用exec()
或任何事件循环旋转函数(如waitForXxx
)是个坏主意。你正在为一个固有的异步系统编写同步代码,在这个过程中愚弄自己。
在GUI线程中执行的代码(例如QWidget
构造函数)不应执行以下任何操作:
请注意,QDialog
是一个QWidget
。
以下示例解决了以下建议:
QtConcurrent::run
在线程池中运行计算和文件访问。accepted
和rejected
信号在插槽中作出反应。使用show()
代替exec()
。class Dialog : public QDialog {
QFuture<void> m_init;
static void init(Dialog * dialog) {
// do heavy initialization work here
// You can't access any QWidget methods (and those of derived classes),
// nor QPixmap. QImage/QPainter are OK.
// This code should be dealing with file/network reading, computations, etc.
}
public:
Dialog(QWidget * parent = 0) : QDialog(parent), ... {
// Set up child widgets etc. here
...
connect(&m_watcher, SIGNAL(finished()), SIGNAL(ready()));
m_watcher.setFuture(m_init = QtConcurrent::run(init, this));
}
Q_SIGNAL void ready(); // the dialog is initialized and ready for use
bool isReady() const { return m_init.isFinished(); }
}
class DialogUser : public QWidget {
QScopedPointer<Dialog> m_dialog;
Q_SLOT void showDialog() {
if (!m_dialog) {
m_dialog.reset(new Dialog(this));
connect(m_dialog, SIGNAL(ready()), m_dialog, SLOT(show()));
connect(m_dialog, SIGNAL(accepted()), SLOT(dialogAccepted()));
connect(m_dialog, SIGNAL(rejected()), SLOT(dialogRejected()));
} else {
if (m_dialog.isReady()) m_dialog.show();
// otherwise the ready() signal hasn't been emitted yet and the
// dialog will show itself
}
}
Q_SLOT void dialogAccepted() {
// react to the dialog's acceptance
...
}
Q_SLOT void dialogRejected() {
// react to the dialog's rejection
...
}
public:
...
};