PDA

View Full Version : Using QtScript to interact with blocking modal dialogs



divad12
21st January 2011, 20:27
Hello,

I am attempting to use QtScript to perform GUI testing. However, in my application, there are modal dialogs that block script execution when invoked, such as the Tools > Options dialog. How can I control these dialogs (click their buttons, etc.) through QtScript?

I have tried several approaches:

Run the script engine in a separate thread: This creates other issues, such as having to delay after emitting a button's clicked() signal, in order to stay in sync with the the main thread.
Separate the invocation of the modal dialog in an entirely new thread: I get a runtime error:

QObject::setParent: Cannot set parent, new parent is in a different thread
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QApplication(0x7fff4474fe10), parent's thread is QThread(0x6d7640), current thread is ScriptFuncThread(0x76d9c0)

Separate the QtScript that interacts with the dialog into a new thread. This works some of the time; however, occasionally, I get a segmentation fault. (I did some googling and it may be due to that QScriptEngine is not thread-safe - http://www.qtcentre.org/threads/27139-QtScript-how-to-reload-current-script)
Refactor the dialog C++ code to call setModal(true) and then show() instead of exec(), and then connect a handler slot to the dialog's finished(int) signal. This works, but I would rather not refactor the existing C++ code for all my dialogs from




int result = dialog_widget->exec();
dialog_widget->handleResult(result);


to


connect(dialog_widget, SIGNAL(finished(int)), dialog_widget, SLOT(handleResult(int)));
//...
dialog_widget->setModal(true);
dialog_widget->show();


Could there be a way to send events from the main window event loop to the QDialog's local event loop?

This is not a problem with non-modal dialogs; I can use QtScript to interact with them without trouble.

Thank you.

bothorsen
23rd January 2011, 08:40
My own solution would be your #4.

But, are you sure the connection from your script signals are done with queued connections?

Another option is to have a dispatcher QObject between your script code and the dialog. This object receives the signals from the script and calls postEvent(dialog-object, someevent). You have to implement custom events for this to work, though.