Test modal dialog with Qt Test

前端 未结 4 841
青春惊慌失措
青春惊慌失措 2021-01-05 09:34

I am trying to write a unit test for a GUI application using the QTestLib. The problem is that one of the slots creates a modal dialog using exec() and I found

相关标签:
4条回答
  • 2021-01-05 10:15

    You can keep the interaction in the same thread by delaying its execution until the dialog event loop starts.

    For example just before the exec() call, you use either QTimer::singleShot with 0 as interval or QMetaObject::invokeMethod with connection type Qt::QueuedConnection to invoke the slot that needs to be executed while the dialog is shown.

    0 讨论(0)
  • 2021-01-05 10:28

    related question's answer has some extra details about flushing the event queue during a test: Qt event loop and unit testing?

    0 讨论(0)
  • 2021-01-05 10:31

    You can also post the events before calling exec(). As soon as the dialog has been constructed after the exec() call, the events will be executed.

    For example to test an Esc key press (means reject/close the dialog):

    // create a dialog
    QDialog d = ...
    //post an Escape key press and release event
    QApplication::postEvent(&d, new QKeyEvent(QEvent::KeyPress  , Qt::Key_Escape, Qt::NoModifier) );
    QApplication::postEvent(&d, new QKeyEvent(QEvent::KeyRelease, Qt::Key_Escape, Qt::NoModifier) );
    // execute and check result
    int ret = d.exec();
    QCOMPARE(ret, static_cast<int>(QDialog::Rejected));
    
    0 讨论(0)
  • 2021-01-05 10:34

    The solution I use in command line applications which use Qt libraries meant for GUIs is the singleShot, as this answer alludes. In those cases it looks like this:

    QCoreApplication app(argc, argv);
    
    // ...
    
    QTimer::singleShot(0, &app, SLOT(quit()));
    return app.exec();
    

    So in your case I imagine it would look something like this:

    QDialog * p_modalDialog = getThePointer(); // you will have to replace this with
                                               // a real way of getting the pointer
    
    QTimer::singleShot(0, p_modalDialog, SLOT(accept()));
    
    p_modalDialog->exec(); // called somewhere else in your case
                           // but it will be automatically accepted.
    
    0 讨论(0)
提交回复
热议问题