【发布时间】:2014-11-20 02:29:03
【问题描述】:
我有一个基于原始 XLib 的现有(大型)X 应用程序。我想使用 Qt 4 向这个应用程序添加额外的窗口。最好的方法是什么?
迄今为止的研究:
(如果细节很重要,我现在正在研究 Qt 4.7.4。)
我现有的应用程序在循环中调用XtAppNextEvent 来处理其事件。我希望做的是用基于 Qt 的事件循环替换这个事件循环,让 Qt 处理自己的事件,并为非 Qt 事件调用XtDispatchEvent。
我已经找到了处理 X 事件的 Qt 部分(在src/gui/kernel/qapplication_x11.cpp、QApplication::x11ProcessEvent 中)。我相信这个功能的关键部分是:
QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window);
确定事件是否引用 Qt 知道的窗口。对于非 Qt 窗口,这将返回 NULL。在此之后有几个处理异常,然后是这样的块:
if (!widget) { // don't know this windows
QWidget *popup = QApplication::activePopupWidget();
if (popup) {
// ... bunch of stuff not involving widget ...
}
return -1;
}
我希望此时会有一个事件回调,该回调会被非 Qt 相关的窗口事件调用,因此我可以简单地在派生的 QApplication 中实现一个虚函数并继续应用程序的现有事件处理.我可以添加这样的函数并重建 Qt,但如果可能的话,我宁愿避免这样做。
我是否在正确的轨道上,还是有更好的方法?
我发现了与此类似的现有问题,但它们都适用于 Windows(MFC 或 .NET)。这是 X 特有的。
【问题讨论】:
-
我认为您不需要替换现有的事件循环。您可以让原始事件循环继续处理现有事件,而只需添加一个 Qt 事件循环来处理 Qt 事件。有关如何在辅助线程中启动 Qt 事件循环的信息,请参阅 stackoverflow.com/questions/22289423/…。如果您想将 Qt 窗口嵌入到您现有的窗口中,请参阅 QX11EmbedWidget:qt-project.org/doc/qt-4.8/qx11embedwidget.html 我不能 100% 确定这是否适合您的用例——是吗?
-
@JKSH:不幸的是,线程对我不起作用,因为 Qt 部分和非 Qt 部分都依赖于不是线程安全的共享组件(也就是说,如果它们在同一个进程,只能有一个线程)。我会研究 XEmbed,这可能是处理这个问题的好方法。
标签: c++ qt x11 event-loop