MFC应用程序中的Qt DLL - 如何使QDialog *真正*模态?

时间:2018-02-07 16:01:23

标签: c++ qt mfc event-loop

目前我正在使用 Qt 5.9.2 (MSVC 2015编译器)开发Windows DLL,该DLL应由现有的商业MFC应用程序加载。根据此应用程序的请求,应显示QDialog的模态实例。 由于QApplication::exec()将阻止整个应用程序,因此我使用以下代码“模拟”事件循环:

void Core::createQApplicationInstance()
{
    // Check, if there's already a 'QApplication' instance running (unlikely)
    if (!QApplication::instance())
    {
        int argc = 1;

        // Create a new 'QApplication' instance
        m_app = new QApplication(argc, nullptr);

        // Create a 'QTimer' instance to call 'processEvents' periodically:
        // We can't run 'm_app->exec()' because it would block everything,
        // so we'll use this 'hacky-whacky' method here
        m_timer = new QTimer;

        // Connect the timer's timeout to the app's 'processEvents' via a lambda
        QObject::connect(
            m_timer,
            &QTimer::timeout,
            [&]()
            {
                m_app->processEvents();
            }
        );

        // Start the timer with the fixed 'message' interval
        m_timer->start(kMsgInterval);
    }
}

如果我的DLL现在应该显示模式对话框,它可以(部分)使用以下代码:

{...}
        case eUserIGeneral:
        {
            qDebug() << "<< eUserIGeneral";

            QDialog w;

            w.setModal(true);

            w.exec();

            // --> Code here is executed AFTER the dialog has been closed
        }
        break;
        //-------------------------------------------------------------------

{...}

w.exec()之后的代码实际上将在对话框关闭后执行(按预期)。但是,主应用程序仍然保持响应,并且不受我的对话框模式的影响,这不是我预期的行为。

如何在调用模态DLL对话框时确保主应用程序中的输入被锁定?

1 个答案:

答案 0 :(得分:0)

虽然我对您的问题没有真正的答案,但是您的代码有太多错误,无法在评论中正确解释。所以我写这个作为答案。

QApplication::exec():我强烈建议修改针对它的决定。如果您希望窗口是模态的,那么为什么阻止整个应用程序会出错?#34;直到关闭?请注意,您不会阻止应用程序的Qt部分,只能阻止调用exec的部分。

QTimer:计时器只能在事件循环中运行。所以m_app->processEvents()永远不会执行,或者你已经有一个事件循环在运行。无论哪种方式,计时器都没用。

w.setModal():如果这样做对您不正确,请查看setWindowModality()

w.exec():忽略setModal()的值。阅读setModal()exec()的文档以了解更多信息。

w.exec():执行事件循环。如果这有点像你想要的那样,QApplication::exec()也应该有效。只需确保完成后退出主事件循环。

w.exec():对话框关闭后未执行。在显示对话框时执行。它会阻塞,直到对话框关闭。因此,您将开始执行它,显示对话框,关闭对话框,然后从中返回。阅读exec()的文档以了解更多信息。