【问题标题】:QT How to embed an application into QT widgetQT 如何将应用程序嵌入到 QT 小部件中
【发布时间】:2013-08-30 15:18:12
【问题描述】:

在我们的项目中,我们有三个独立的应用程序,我们必须开发一个控制这三个应用程序的 QT 控制应用程序。主窗口将分为三个子窗口 - 每个子窗口显示另一个应用程序。
我想使用QX11EmbedWidgetQX11EmbedContainer 小部件,但有两个问题:

  1. QX11Embed* 基于 X11 协议,我不知道它是否支持 Windows 操作系统等非 x11 系统。
  2. 自 QT 5 以来,这些类不存在,QT 文档没有提及原因。

所以我不知道是否使用它 - 我很乐意得到答案。
此外,我看到 QT 5.1 包含 QWidget::createWindowContainer(); 函数,在某些帖子中看起来这应该是 X11Embed 的替代品。谁能详细解释一下我如何使用此功能创建一个 QT 小部件,该小部件将在其内部运行另一个应用程序(例如计算器)?

我在 Google 上搜索了很多,但没有找到我的 Qs 的答案。
谁能帮帮我吗?我走对了吗?
谢谢!

【问题讨论】:

    标签: c++ qt qwidget qx11embedcontainer


    【解决方案1】:

    如果所有三个独立的应用程序都是用 Qt 编写的,并且您有它们的源代码,那么您应该能够通过 Qt 中 GUI 对象的父级来统一它们。

    http://qt-project.org/doc/qt-4.8/objecttrees.html

    http://qt-project.org/doc/qt-4.8/widgets-and-layouts.html

    http://qt-project.org/doc/qt-4.8/mainwindows-mdi.html

    如果您无法以这种方式访问​​它们,那么您所说的就像 3rd 方窗口管理。这有点像编写一个 shell,比如 Windows 资源管理器,它可以操纵其他窗口应用程序的状态和大小。

    使用 Spy++ 或 AutoIt Spy for Windows 之类的程序以及其他操作系统的类似程序,并了解您要控制的窗口的识别标记,如类、窗口标题等。或者您可以启动 exe自己在QProcess::startDetached() 之类的事情中。

    http://qt-project.org/doc/qt-5.1/qtcore/qprocess.html#startDetached

    然后使用依赖于操作系统的调用来控制窗口。 Qt 库没有为第三方窗口内置这些东西,仅适用于您启动的 QApplication 下的那些。 AutoHotKey 或 AHK 有很多这样的例子。它是一种脚本语言,用于在 windows 环境中自动执行很多操作,并且还有适用于 Mac 的端口(虽然我自己没有尝试过 mac 端口)。

    所以最后你可能会通过这样的调用来寻找你的窗口:

    #include <windows.h>
    
    HWND hwnd_1 = ::FindWindow("Window_Class", "Window Name");
    LONG retVal = GetWindowLongA(hwnd_1, GWL_STYLE); // to query the state of the window
    

    然后像这样操作窗口的位置和状态:

    ::MoveWindow(hwnd_1, x, y, width, height, TRUE);
    ::ShowWindow(hwnd_1, SW_SHOWMAXIMIZED);
    

    如果您为正在操作的窗口正确设置了窗口标志,您甚至可以在您正在控制的窗口上绘制小部件。

    transparent QLabel with a pixmap

    Cannot get QSystemTrayIcon to work correctly with activation reason

    在执行所有这些操作时,Windows 中出现的一些问题是,当 Windows UI 设置的显示缩放与您期望的不同时,如果您想很好地使用任务栏,以及处理您正在操作的程序的所有模态窗口。

    所以总的来说,它是可行的。 Qt 将为执行这些命令提供一个很好的界面,但最终您需要进行大量工作和调试才能将其放入一个漂亮、可靠的窗口管理器中。

    希望对您有所帮助。

    【讨论】:

    • 首先谢谢你回答我,我开始以为没人能回答我。我无权访问源代码。 2 问:你对 QWidget::createWindowContainer(); 了解多少?功能,它可以完成所有工作吗? 2. 如果您的解决方案需要大量移植到 Windows - 也许不值得 - 而缩短的解决方案是在 .NET 中为 windows 编写应用程序,而我不知道在 Linux-Ubuntu 中编写应用程序?
    • 我之前没用过createWindowContainer。看起来这是升级任何类型的QWindow 的捷径,例如场景图或 Qt Quick 或 OpenGL 窗口,以具有与其他 QWidget 一起使用的完整窗口装饰。看起来它不能只接受任何 HWND id...blog.qt.digia.com/blog/2013/02/19/…
    • 处理窗口并不难。它确实需要研究和工作,但在 Windows 中启动和操作它们应该不会超过几个小时。我还没有在 Linux 和 OSX 中完成它,但这应该只是获得正确调用的问题。
    • 此外,如果您在 .NET 中正确执行此操作,您可能能够使用它们的端口在其他操作系统中执行类似的调用。我没有经常使用.NET,但听起来有些人已经为 AHK 做过。 ironahk.net
    • 所以看ironAHK,它仍然是一个相当年轻的项目。它可能可以做一些,但现在有很多throw new NotImplementedException();。找到执行C# 路由的示例可能是一个好的开始。
    【解决方案2】:

    我自己从未尝试过,但从 Qt 5.1 的文档中我会尝试 QWindow::fromId(WId id),它为您提供了一个 QWindow,它应该可以嵌入 createWindowContainer:

    QWindow * QWindow::fromWinId(WId id) [静态] 创建一个本地 由另一个进程或使用创建的窗口的表示 Qt 下的原生​​库。

    给定本机窗口的句柄 id,此方法创建一个 QWindow 调用方法时可用于表示窗口的对象 像 setParent() 和 setTransientParent()。这可以使用,在 支持它的平台,在容器内嵌入窗口或 让一个窗口贴在另一个进程创建的窗口之上。

    但不能保证。 :-)

    【讨论】:

    • 我们如何才能将句柄 id 获取到外部应用程序(通过 QProcess 创建)?
    猜你喜欢
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 2010-12-18
    • 2015-01-18
    • 1970-01-01
    • 2019-09-05
    相关资源
    最近更新 更多