【问题标题】:How to close and exit a QDialog shown with exec() after a timeout?超时后如何关闭和退出用 exec() 显示的 QDialog?
【发布时间】:2017-12-20 23:42:51
【问题描述】:

我正在尝试使用 QTimer 的超时关闭 QDialog。

到目前为止,我已经尝试过这样做:

QDialog dlg;
.. 
..
myTimer.start(60000); // 60 s
connect(&myTimer, SIGNAL(timeout()),
        &dlg, SLOT(close())));

dlg.exec();
qWarning() << "---timer expired or key pressed--";

但是当超时被触发并且close 槽被执行时,事件循环并没有退出。 reject 插槽的行为相同。我知道done 插槽应该具有预期的行为,但由于它需要一个额外的参数(int r),它不能直接连接到timeout() 信号。

当然,我可以“中继”timeout 信号来提供缺失的参数,但还有其他更直接的方法吗?

谢谢。

【问题讨论】:

  • 如何使用 done() 作为插槽:“关闭对话框并将其结果代码设置为 r。如果此对话框与 exec() 一起显示,则 done() 会导致本地事件循环完成, 和 exec() 返回 r。”
  • 从堆中创建你的对话框,不要用dlg-&gt;exec()阻塞事件循环。
  • “事件循环未退出”是什么意思?对话框没有关闭?
  • Yes 对话框未关闭且 eventloop 未退出。但真正的代码更复杂,我怀疑所有带有 QDialog 的信号和插槽都在超时时断开(信号连接到多个插槽),因此close 插槽可能永远不会被调用。

标签: c++ qt


【解决方案1】:

dlg.exec();是同步的,他返回接受或拒绝的答案。

void MainWindow::btnClicked() {
    Dialog *dialog = new Dialog();
    dialog.exec();
    qDebug() << "test"; 
    // while dialog not destroyed (rejected, accepted) Print will not happen never. 
}

您可以在 Dialog 类中使用 QTimer 的一种方式:

Dialog::dialog(...) {
    //constructor
    QTimer::singleShot(60000, this, SLOT(close()));
}

或者不使用 dialog.exec();使用 dialog.show();如果你想要对话框,让它成为你可以使用的模态:

void MainWindow::btnClicked() {
    Dialog *dialog = new Dialog();
    dialog->setModal(true);
    dialog->show();
    qDebug() << "test"; //The "test" will be printed, and you can use QTimer :))
 }

【讨论】:

    【解决方案2】:

    我建议给对话框自己的计时器(即在执行对话框之前在本地实例化一个 QTimer):

    QTimer dlg_timer;
    dlg_timer.start(60000); // 60 s
    connect(&dlg_timer, SIGNAL(timeout()), &dlg, SLOT(close()));
    dlg.exec();
    dlg_timer.stop();
    

    正如 OP 在他们的评论中所担心的那样,如果计时器超时信号已连接到某个其他插槽,则在连接对话框关闭之前,并且在该插槽中调用 QTimer::disconnect(),则永远不会调用对话框关闭插槽。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多