如何从QProcess中获取QWidgets并与之交互
How to obtain and interact with QWidgets from QProcess
我有Application A
,这是一个使用Qt库的第三方Windows应用程序(带有GUI)。
我想写Application B
,它将负责启动Application A
。我希望Application B
也能找到Application B
(QWidgets
)上的按钮,并向它们发送鼠标输入(单击,双击等)。
我可以通过在QProcess
上使用start
函数来运行Application A
。
我如何从我的QProcess
实例中执行以下操作:
- 获取进程的顶层窗口
- 通过名称或(其他可识别的属性)获取小部件
- 获取小部件的标题,颜色和坐标(可能还有一些其他数据)
- 发送鼠标移动和点击事件到特定坐标
- 给一个小部件键盘焦点
- 发送键盘按键
注意-我知道如何用Windows API做到这一点,但要求通过Qt的方式。特定的Application A
问题不使用本机窗口系统,因此窗口句柄不会显示在spy++或Windows API函数中。
更新1 -似乎无法通过进程的子进程获得任何有意义的对象
为进程获取子部件的尝试:
QProcess* process = new QProcess();
QString program = ""C:\Program Files (x86)\foo\bar.exe"";
process->start(program);
auto widgets = process->findChildren<QWidget*>("", Qt::FindChildrenRecursively);
auto i = widgets.count();
// i = 0
如果我找到类型<QObject*>
的孩子,我得到4个结果。我使用metaObject()->className()
看到我有两对qwindowspiperreader和QWinOverlappedIoNotifier对象。
更新2 -无法从另一个进程创建/注入窗口
我注意到,当我运行QProcess时,我可以使用Windows API函数来获得顶层窗口(仅限顶层)。我在Qt文档中读到,你可以使用QWindow::fromWinId从另一个进程中的窗口句柄创建一个QWindow。
使用这个函数会抛出一个0xC0000005: Access violation reading location 0x00000000.
错误。我没有传入空句柄。我使用reinterpret_cast将HWND
转换为WId
类型。只有当我事先创建QApplication时,它才会创建一个QWindow。
新的QWindow将没有子窗口(使用window->findChildren<QObject*>("", Qt::FindChildrenRecursively);
,我假设创建QWindow不会带来关联的子窗口)
更新3 -我目前正在阅读进程间通信是否可以使用
我遇到了关于Qt中ICP的各种线程,问题和代码片段,到目前为止,我没有看到任何具体表明当其中一个进程是第三方时ICP是可能的。
我已经看到,Squish Gui测试工具允许您查询QWidget属性。
这永远不会像你想的那样工作。
如果您真的希望直接控制其他应用程序,您必须将您的代码注入该应用程序。让我们假设应用程序使用动态链接的Qt。
-
构建一个二进制兼容的Qt版本,使用与构建您打算调整的应用程序相同的编译器。
-
将应用程序的Qt替换为您的Qt。如果您的代码应该是二进制兼容的,那么一切都应该正常工作。如果没有,说明二进制兼容性不存在,你必须调整一些东西,直到它们正常工作。
-
编辑你的Qt,在
QApplication
构造函数的末尾添加一个钩子来初始化你的代码。这使得提供QApplication
的Qt模块依赖于你的代码。 -
把你的代码放入一个dll, widget(对于Qt 5)或gui(对于Qt 4)模块现在依赖。
-
再次用你的Qt替换应用程序,用钩子启动你的代码。
您的代码当然需要是异步的,并且将通过检查qApp->activeWindow()
, qApp->allWidgets()
等来监视应用程序的进度。
这几乎是唯一的方法。当然,您可以以任何您想要的方式注入代码,但是您需要使用一个与二进制兼容的Qt版本来编译代码。请注意,二进制兼容性不仅仅包括使用相同的编译器版本和Qt版本。许多configure
开关也必须是相同的
- Qt VTK交互风格的信号到小部件
- Qt Quick-如何仅从c++代码与qml属性交互
- 复制和交换习惯用法与移动操作之间的交互
- 为什么在访问 vtkRenderWindow 的"交互器"变量时会发生段错误?
- Qt QGraphicsProxyWidget 与 QGraphicsScene 的交互
- 使用 Python 事件并与 C++ 交互
- 函数-本地枚举声明和 ADL 的交互
- 如何在扩展的QQuickItem中与模型交互
- 寻找C++中数组和cout交互的解决方案
- C++继承和"常量"交互的问题
- 在 QLayout 中创建和删除自定义 QWidgets 时出现 RAM 问题
- 以太坊与外部 c++ 库的交互稳定性
- QWidget收听其他QWidgets事件
- 玩家移动和碰撞之间的交互问题
- C++ 和 Lua 函数之间的交互与 3D 矢量参数
- 内存分配究竟是如何发生的,Java和C如何交互以跟踪同一对象?
- 如何包装对象,使它们成为无法交互的单独类型?
- 通过交互器获取向量中的索引
- 如何在python中的PyArrow和C++中的Arrow之间进行交互时将PyArrow表转换为Arrow表
- 如何从QProcess中获取QWidgets并与之交互