Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模态QProgressDialog::setValue()通过嵌套事件循环导致崩溃_C++_Qt_Qeventloop_Queued Connection_Qprogressdialog - Fatal编程技术网

C++ 模态QProgressDialog::setValue()通过嵌套事件循环导致崩溃

C++ 模态QProgressDialog::setValue()通过嵌套事件循环导致崩溃,c++,qt,qeventloop,queued-connection,qprogressdialog,C++,Qt,Qeventloop,Queued Connection,Qprogressdialog,我刚刚编写了一些基于QThread的代码,执行了一个大的计算。要可视化进度,我需要打开一个QProgressDialog。该对话框是应用程序模式(使用open()),因为我不希望在计算期间修改主窗口。线程发出各种信号,允许GUI和线程之间基于状态机的通信 线程的worker对象发出的两个信号是“Progress”和“Finished”。如果发出“Progress”,我将使用setValue()更新QProgressDialog。如果发出“完成”,则对话框将被销毁 计算结束时发生以下情况: 发出

我刚刚编写了一些基于QThread的代码,执行了一个大的计算。要可视化进度,我需要打开一个QProgressDialog。该对话框是应用程序模式(使用open()),因为我不希望在计算期间修改主窗口。线程发出各种信号,允许GUI和线程之间基于状态机的通信

线程的worker对象发出的两个信号是“Progress”和“Finished”。如果发出“Progress”,我将使用setValue()更新QProgressDialog。如果发出“完成”,则对话框将被销毁

计算结束时发生以下情况:

  • 发出“进度”事件(100%)
  • “Finished”(完成)是在
  • 由于“进度”事件而调用setValue(100)
  • 因为对话框是模态的,所以setValue()调用processEvents()
  • processEvents()传递“已完成”事件
  • “完成”事件导致对话框在中间被破坏。 导致崩溃的setValue()的
QProgressDialog通过调用setValue()中的processEvents()打破了我的体系结构。此外,我的编码约定禁止使用任何嵌套事件循环(如exec()等)

我有两个问题:

  • 为什么模态对话框需要嵌套的事件循环?从我的理解来看,阻止父窗口的输入似乎不需要这样做

  • 是否可以以模式方式使用QProgressDialog,但不使用嵌套的事件循环


  • 您应该使用
    deleteLater()
    销毁
    QProgressDialog
    。删除
    QProgressDialog
    对象的事件在属于
    QProgressDialog
    对象本身的函数中处理,这归结为调用
    delete this的合法性在C++成员函数中,您可以从iSoCP++ C++ FAQ中参考有关此的更多信息。其要点是,你应该保证在自杀后不再访问该对象的任何成员

    由于在Qt的
    QProgressDialog::setValue()
    实现中无法保证这一点,因此
    delete
    s
    QProgressBar
    这样的事件将在下次访问对象的任何成员时(在成员函数中拾取时)愉快地调用UB
    deleteLater
    是专门为解决这类问题而设计的,因为延迟删除事件是以特殊方式处理的(它们不会被
    QCoreApplication::processEvents()
    拾取)。这意味着<代码> qPrimeStReals< /Cord>对象将在<代码> SETValue/COD>之后被返回到事件循环中,而不是在执行<代码> SETValue…< /P>的中间。
    在这种情况下,请始终使用
    deleteLater
    。在事件中使用plain
    delete
    时,您必须确保在执行此对象的成员函数时不会处理此事件,并且不会因为从该对象发出信号(使用直接信号/插槽连接)而执行此事件,因为,信号只是一个成员函数,其实现由Qt的MOC提供).

    如何“破坏”对话框?您是否正在使用
    deleteLater()
    ?您的问题标题与实际编号的问题不匹配。请让它们保持一致。@Mike:我使用delete。也许deleteLater是一种解决方法,我会尽快尝试。setModal()/show()在这里不起作用。我已经使用open()。QProgressDialog很特别,因为不管我使用哪种模态,它都会调用setValue()中的事件循环。@Silicomancer,那么,嵌套事件循环与您描述的崩溃无关。无论如何,我已经回答了您关于在没有嵌套事件循环的情况下设置模式对话框的问题(我是否正确回答了您的问题?),使用
    open()
    似乎也是另一种方式……对不起,Mike,但我想您没有回答这个问题。我知道如何在没有事件循环的情况下设置模态对话框。我的问题是如何设置没有事件循环的模式QProgressDialog。但我想这根本不可能,因为QProgressDialog::setValue()的特殊行为。也许稍后删除是一个很好的解决方法。我会在尝试后给出反馈。我同意。我会努力的。Qt人员决定通过实现嵌套循环来支持设计糟糕的应用程序,这真是太糟糕了。我认为他们应该放弃对这些残破建筑的支持。如果您删除/编辑答案中的模态部分(不适用于我的情况),我可以接受您的解决方案。@Silicomancer,我已删除了答案中有关模态的部分。但我认为你也必须把它们从你的问题中删除。具体来说,最后的两个问题似乎与您已经在使用
    open()
    以及您知道如何在没有嵌套事件循环的情况下设置模式对话框的事实相冲突。。。