如何在qt中完成构造函数的执行之前显示表单?

时间:2014-08-01 13:09:55

标签: c++ qt

我正在开发一个exec()的应用程序,它是另一个对话框。 这里的问题是在构造函数中执行庞大的任务持有exec()的UI。 一旦构造函数完成,它就会显示表单。

我的问题是如何同时显示表单和exec()构造函数。

这就是我现在这样做的方式,

    Event2 ev2_obj(this);
    if(Event1::Accepted == ev2_obj.exec())
    {}

2 个答案:

答案 0 :(得分:0)

如果没有一个不同的应用程序启动它自己的GUI,我不认为Qt允许你在调用exec()之前显示任何GUI。

正如其他人所建议的那样,考虑将庞大的任务从构造函数中移除。

答案 1 :(得分:0)

使用exec()或任何事件循环旋转函数(如waitForXxx)是个坏主意。你正在为一个固有的异步系统编写同步代码,在这个过程中愚弄自己。

在GUI线程中执行的代码(例如QWidget构造函数)不应执行以下任何操作:

  • 阻止文件操作,
  • 阻止网络运营,
  • 阻止计算。

请注意,QDialog是一个QWidget。 以下示例解决了以下建议:

  1. 使用QtConcurrent::run在线程池中运行计算和文件访问。
  2. 对话框的acceptedrejected信号在插槽中作出反应。使用show()代替exec()
  3. 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:
      ...
    };