【问题标题】:How can I integrate new Qt windows with an existing X application?如何将新的 Qt 窗口与现有的 X 应用程序集成?
【发布时间】: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.cppQApplication::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


【解决方案1】:

我最终得到的解决方案是找到Qt Motif Extension 的副本(Digia 不再直接提供它,因为它现在不受支持,但您仍然可以找到qtmotifextension-2.7-opensource.zip 的副本)。在那里,qtmotif.hqtmotif.cpp 模块展示了如何创建一个 QAbstractEventDispatcher 来处理 Xt/Motif 和 Qt 组件的 X 事件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2012-05-14
    • 2011-08-15
    相关资源
    最近更新 更多