简体   繁体   English

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

[英]Qt DLL in MFC app - How to make QDialog *really* modal?

At the moment I am developing a Windows DLL with Qt 5.9.2 (MSVC 2015 compiler), which should be loaded by an existing, commercial MFC application. 目前,我正在开发带有Qt 5.9.2 (MSVC 2015编译器)的Windows DLL,应该由现有的商用MFC应用程序加载。 Upon request of this application a modal instance of QDialog should be displayed. 应此应用程序的请求,应显示QDialog的模式实例。 Since QApplication::exec() would block the entire application, I "simulate" the event loop using the following code: 由于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);
    }
}

If my DLL should now display a modal dialog, it works (partially) with the following code: 如果我的DLL现在应该显示一个模式对话框,则可以使用以下代码(部分)运行该对话框:

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

            QDialog w;

            w.setModal(true);

            w.exec();

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

{...}

The code after w.exec() will actually be executed AFTER the dialog was closed (as intended). w.exec()之后的代码实际上将在对话框关闭后执行(按预期)。 However, the main application still remains responsive and is not affected by the modality of my dialog, which Is not as I expected it to behave. 但是,主应用程序仍然保持响应状态,并且不受对话框形式的影响,这与我预期的不一样。

How can I make sure that inputs in the main application are locked when calling a modal DLL dialog? 如何在调用模式DLL对话框时确保主应用程序中的输入被锁定?

Although I don't have a real answer to your question, there too much stuff wrong with your code to be properly explained in a comment. 尽管我对您的问题没有真正的答案,但是您的代码有太多错误,无法在注释中正确解释。 Therefore I am writing this as an answer. 因此,我将其作为答案。

QApplication::exec() : I strongly recommend revising the decision against it. QApplication::exec() :我强烈建议针对它修改决定。 If you want the window to be modal, why would it be wrong to "block the entire application" until it is closed? 如果您希望窗口是模式窗口,为什么在关闭窗口之前“阻止整个应用程序”是错误的? Note that you will not block the Qt part of the application, only the one that calls exec. 注意,您不会阻塞应用程序的Qt部分,只会阻塞调用exec的程序。

QTimer : A timer can only run inside an event loop. QTimer :计时器只能在事件循环内运行。 So the m_app->processEvents() either never executes, or you already have an event loop running. 因此, m_app->processEvents()可能永远不会执行,或者您已经在运行事件循环。 Either way, there is no use for the timer. 无论哪种方式,计时器都没有用。

w.setModal() : If what this does is not correct for you, check out setWindowModality() . w.setModal() :如果这对您不正确,请检出setWindowModality()

w.exec() : Ignores the value of setModal() . w.exec()忽略的值setModal() Read the documentation of setModal() and exec() to find out more. 阅读setModal()exec()的文档以了解更多信息。

w.exec() : Executes an event loop. w.exec() :执行事件循环。 If this somewhat does what you want, QApplication::exec() should work too. 如果这可以满足您的要求,那么QApplication::exec()应该可以工作。 Just make sure to exit the main event loop when done. 只要确保完成后退出主事件循环即可。

w.exec() : Is not executed after the dialog was closed. w.exec() :关闭对话框后不执行。 It is executes while the dialog is shown. 这是执行,而被所示的对话框。 It blocks until the dialog is closed. 它会阻塞直到对话框关闭。 So you will start executing it, show the dialog, close the dialog, and then return from it. 因此,您将开始执行它,显示对话框,关闭对话框,然后从中返回。 Read the documentation of exec() to find out more. 阅读exec()的文档以了解更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM