Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xlib:从同一Qt应用程序中的单独Qt线程测试Qt应用程序时出现意外的异步响应_Qt_X11_Qthread_Gui Test Framework - Fatal编程技术网

Xlib:从同一Qt应用程序中的单独Qt线程测试Qt应用程序时出现意外的异步响应

Xlib:从同一Qt应用程序中的单独Qt线程测试Qt应用程序时出现意外的异步响应,qt,x11,qthread,gui-test-framework,Qt,X11,Qthread,Gui Test Framework,我正在尝试为我的Qt应用程序创建一个测试。目的是通过移动鼠标并使用X11库单击QGraphicsSitems或QWidgets来测试应用程序的GUI 该测试是作为我的Qt应用程序的插件编写的。它会启动一个单独的QThread,并在run()函数中执行鼠标移动。让我们称之为“测试运行线程” 但是,我还需要获得GUI的结构,即各种小部件的位置,因此在“测试运行线程”中,我将遍历QApplication::topLevelWidgets()并找到我感兴趣的小部件。然后我在这个小部件上调用mapToGl

我正在尝试为我的Qt应用程序创建一个测试。目的是通过移动鼠标并使用X11库单击QGraphicsSitems或QWidgets来测试应用程序的GUI

该测试是作为我的Qt应用程序的插件编写的。它会启动一个单独的QThread,并在run()函数中执行鼠标移动。让我们称之为“测试运行线程”

但是,我还需要获得GUI的结构,即各种小部件的位置,因此在“测试运行线程”中,我将遍历QApplication::topLevelWidgets()并找到我感兴趣的小部件。然后我在这个小部件上调用mapToGlobal()来获取它的全局位置。然后,可以将该位置反馈给X11鼠标功能,以将鼠标移动到小部件上

这通常可以正常工作,但偶尔会出现以下错误“Xlib:unexpected async reply” 一些谷歌搜索显示,这可能是由于设置QWidget位置或试图从另一个线程更新它们

但我只是在另一个线程中获取有关小部件的信息。为什么会引起问题(

如果所有这些都失败了,我准备将某种通信队列设置回主(GUI)线程。“测试运行线程”将请求队列上的小部件信息,GUI线程可以响应这些请求

插件启动一个单独的线程来移动鼠标的原因是GUI必须继续响应事件,否则整个练习的要点都会丢失。我知道我也不能使用线程,只需在主线程中定期调用processEvents()移动鼠标。我想这是我的另一个选择

以前有过这种经历的人的任何想法都会非常有用。 谢谢

但我只是在另一个线程中获取有关小部件的信息。为什么 这会引起问题吗(

因为您仍在来回发送X协议消息。toGlobal()一定会向X服务器查询小部件的实际位置(因为它可能已通过其他方式移动)因此,不幸的是,就X而言,“仅仅获取一些信息”并不是一个常量操作。事实上,出于同样的原因,将鼠标从测试线程中移出也是一个大禁忌


在您的情况下,我只需要使用零超时QTimer/processEvents,而忽略线程;设置队列来回移动事件是不值得的,更不用说您需要在代码中添加互斥量(!)。

因此我理解processEvents()调用以确保鼠标事件在从同一主界面(GUI)移动时继续得到处理线程。但您建议使用QTimer的原因是什么?我的意思是,即使QTimer关闭,我仍然在屏幕上移动鼠标,由QTimer触发的代码也不会运行。因为我们现在在一个线程中执行所有操作。假设我调用了processEvents()从QTimer回调中,它将不会被调用。因此,当鼠标在屏幕上移动时,GUI的响应将丢失。这就是为什么我认为可能需要释放GUI线程,并在单独的线程中移动鼠标。调用processEvents()虽然可以使用鼠标移动函数,但这意味着在同一个函数中混合使用Qt和X11代码;如果您正在执行一些繁重的计算,如编码电影或计算Mandelbrot分形,即占用CPU相当长的时间,则应定期调用此函数。通过调用processEvents()从循环中,您可以确保GUI保持响应。您的情况不同:您只需移动鼠标,模拟单击并获取一些结果。这可以在一个从QTimer调用的插槽中完成,该插槽由主GUI线程处理,因此将自动更新GUI。