如何在Linux/X环境下将Qt应用嵌入外部提供的窗口?
在Linux/X环境下将Qt应用渲染到外部提供的XID窗口中
要实现Qt应用渲染到外部应用提供的XID窗口,核心是利用Qt的X11平台原生API,将Qt的根窗口(QWindow/QWidget)依附到外部XID对应的窗口上,以下是具体实现步骤和代码示例:
实现思路
Qt在X11环境下提供了原生接口QNativeInterface::QX11Application,可以直接获取X11的Display*对象,进而通过QWindow::setParentWindow()方法将Qt窗口的父窗口指定为外部提供的XID。
代码实现
1. 必要头文件
#include <QApplication> #include <QWindow> #include <QNativeInterface/QX11Application> #include <X11/Xlib.h> #include <cstdlib> #include <cstring>
2. 主函数逻辑
int main(int argc, char *argv[]) { QApplication app(argc, argv); // 解析外部传入的父窗口XID(示例参数格式:--parent-xid <xid数值>) Window parentXid = 0; for (int i = 1; i < argc; ++i) { if (strcmp(argv[i], "--parent-xid") == 0 && i + 1 < argc) { parentXid = static_cast<Window>(strtoull(argv[i+1], nullptr, 10)); break; } } // 未传入XID时正常启动(作为 fallback) if (parentXid == 0) { QWidget w; w.setWindowTitle("Qt Standalone Window"); w.resize(600, 400); w.show(); return app.exec(); } // 获取X11 Display 对象 Display* display = QNativeInterface::QX11Application::display(); if (!display) { fprintf(stderr, "Failed to get X11 Display\n"); return 1; } // 创建Qt窗口并绑定到外部XID QWindow embedWindow; embedWindow.setFlags(Qt::FramelessWindowHint); // 禁用自身窗口边框,使用父窗口边框 embedWindow.setParentWindow(WId(parentXid)); // 设置父窗口为外部XID // 将QWidget嵌入到该窗口中(如果需要Widget层级的UI) QWidget contentWidget(&embedWindow); contentWidget.setAutoFillBackground(true); contentWidget.setBackgroundRole(QPalette::Window); contentWidget.resize(600, 400); // 初始大小,可监听父窗口变化动态调整 contentWidget.show(); embedWindow.resize(contentWidget.size()); embedWindow.show(); return app.exec(); }
编译注意事项
- 确保项目链接X11库:在CMake配置中添加以下内容(Qt6为例):
find_package(Qt6 REQUIRED COMPONENTS Widgets) find_package(X11 REQUIRED) add_executable(qt_embed_external_xid main.cpp) target_link_libraries(qt_embed_external_xid PRIVATE Qt6::Widgets X11) - 代码需针对X11平台编译,可通过宏
#ifdef QT_X11_SUPPORT包裹平台相关代码,保证跨平台兼容性。
关键注意点
- 权限问题:Qt应用和外部窗口的运行用户需一致,否则X11会拒绝窗口嵌入请求。
- 窗口同步:可通过监听X11的
ConfigureNotify事件,同步外部窗口的大小变化到Qt窗口,避免内容显示不全。 - 窗口属性:外部窗口需允许子窗口嵌入,通常默认支持,若出现问题可检查外部窗口的
_NET_WM_ALLOWED_ACTIONS属性是否包含嵌入权限。
内容的提问来源于stack exchange,提问作者MateuszL
相关产品推荐
相关产品推荐

