Xlib: unexpected async reply when testing Qt application from a separate QThread within same Qt application

StackOverflow https://stackoverflow.com/questions/15779226

Вопрос

I am trying to create a test for my Qt appication. The aim is to test the GUI of the application by moving the mouse around and clicking on QGraphicsItems or QWidgets using the X11 library.

The test is written as a plugin for my Qt application. It launches a separate QThread and in the run() function I do the mouse moving. Lets call this the 'test running thread'

However I also need to get the structure of the GUI i.e. the location of various widgets, so in the 'test running thread' I go through the QApplication::topLevelWidgets() and find the one I am interested in. Then I call mapToGlobal() on this widget to gets its global position. This position can then be fed to the X11 mouse functions to move the mouse over the widget.

This works generally but once in a while I get this error 'Xlib: unexpected async reply' Some googling revealed that this can be due to setting QWidget positions or trying to update them from another thread.

But I simply get information about widgets in another thread. Why would that cause a problem ? :(

If all else fails, I am prepared to setup some kind of communication queue back to the main(GUI) thread. The 'test running thread' will place requests for information about widgets on the queue and the GUI thread can respond to them.

The reason why the plugin launches a separate thread to move the mouse is because the GUI must continue to respond to events otherwise the entire point of the exercise is lost. I know that I could also not use a thread, and simply move the mouse in the main thread calling processEvents() regularly. Thats the other option I have I guess.

Any ideas from someone who has been down this route before would be very helpful. Thanks !

Это было полезно?

Решение

But I simply get information about widgets in another thread. Why would that cause a problem ? :(

Because you are still sending X protocol messages back and forth. toGlobal() is sure to query the X server about the actual position of the widget (since it may have been moved by some other mean). So unfortunately, 'just getting some information' is not a const operation as far as X is concerned. Actually, moving your mouse from the test thread is a big no-no as well for the same reason.

In your case, I would simply use a zero-timeout QTimer/processEvents and forget about the thread; it's not worth the trouble of setting up queues to move events back and forth, not to mention you need to add mutexes (!) to your code.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top