MFC 应用程序中的 Qt DLL - 如何使 QDialog *真正* 模态?
Posted
技术标签:
【中文标题】MFC 应用程序中的 Qt DLL - 如何使 QDialog *真正* 模态?【英文标题】:Qt DLL in MFC app - How to make QDialog *really* modal? 【发布时间】:2018-02-07 16:01:23 【问题描述】:目前我正在使用 Qt 5.9.2(MSVC 2015 编译器)开发一个 Windows 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 对话框时锁定主应用程序中的输入?
【问题讨论】:
M... 除了在自己的新线程上创建 Qt 应用程序实例并旋转事件循环之外,我无法清楚地看到其他方式。这将如何与 MFC UI 线程对话是另一回事和有趣的效果。 您基本上只是在显示对话框之前禁用所有者窗口。例如。EnableWindow(hWndOwner, FALSE);
并在模态结束后再次启用它。
【参考方案1】:
虽然我对您的问题没有真正的答案,但您的代码有太多错误,无法在评论中正确解释。因此,我写这个作为答案。
QApplication::exec()
:我强烈建议修改反对它的决定。如果您希望窗口是模态的,为什么“阻止整个应用程序”直到它关闭是错误的?请注意,您不会阻塞应用程序的 Qt 部分,只会阻塞调用 exec 的部分。
QTimer
: 定时器只能在事件循环中运行。所以m_app->processEvents()
要么永远不会执行,要么你已经有一个事件循环在运行。无论哪种方式,计时器都没有用。
w.setModal()
:如果这对您不正确,请查看setWindowModality()
。
w.exec()
:忽略setModal()
的值。阅读setModal()
和exec()
的文档以了解更多信息。
w.exec()
:执行事件循环。如果这有点符合您的要求,QApplication::exec()
也应该可以工作。只要确保完成后退出主事件循环即可。
w.exec()
: 对话框关闭后不执行。它在显示对话框时执行。它会一直阻塞,直到对话框关闭。所以你将开始执行它,显示对话框,关闭对话框,然后从它返回。阅读exec()
的文档以了解更多信息。
【讨论】:
以上是关于MFC 应用程序中的 Qt DLL - 如何使 QDialog *真正* 模态?的主要内容,如果未能解决你的问题,请参考以下文章