Automatize QDialog actions



  • Hello,

    I am adapting an existing software to be embedded.
    It is developed with C++ and Qt.

    From the main user interface, a Dialog opens, I have to click down arrow and then Enter to select an item from a list.
    As no keyboard or mouse will be available, I have to automatize those two button clicks.

    My try was to this code:

    df.exec();
    QKeyEvent *event = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);
    QCoreApplication::postEvent (QApplication::focusWidget(), event);
    
    QKeyEvent *event2 = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
    QCoreApplication::postEvent (QApplication::focusWidget(), event2);
    

    I tried replacing QApplication::focusWidget() with QApplication::activeModalWidget() and some other things but without any luck, dialog opens but nothing is pressed, it keeps waiting for manual intervention.

    What is the correct way of doing this?


  • Qt Champions 2016

    Hi
    the df.exec() is blocking. meaning it stay there until ok/cancel pressed and dialog closes so
    the postEvent will run after :)

    I was wondering if u cant directly get the Action and trigger it when dialog opens ?
    Else, you can make a timer and send dialog a signal to make it select and trigger some action.



  • @mrjj I understand, so code under df.exec() will never run.
    "I was wondering if u cant directly get the Action and trigger it when dialog opens ?"
    I tried inserting the code in the dialog constructor but it is also not working, so I don't think so.
    Could you explain the timer workaround?
    Thank you for your help


  • Qt Champions 2016

    @danividanivi
    Hi
    Well postEvent will run after exec() terminates. ( its local event loop)
    The code will not likely work in constructor as dialog is not visible yet.

    You can try ( in ctor of dialog)
    QTimer::singleShot(1000, {
    QKeyEvent *event = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);
    QCoreApplication::postEvent (QApplication::focusWidget(), event);

    QKeyEvent *event2 = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
    QCoreApplication::postEvent (QApplication::focusWidget(), event2);
    } );

    But im wondering how you have the QActions ?
    You cant directly find it and run its trigger() ?


  • Lifetime Qt Champion

    Hi,

    To add to @mrjj, did you consider using QDialog::open ?



  • @mrjj the timer singleShot solution is working like a charm!

    QTimer::singleShot(1000, []() {
          QKeyEvent *event = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);
          QKeyEvent *event2 = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
          QCoreApplication::postEvent (QApplication::focusWidget(), event);
          QCoreApplication::postEvent (QApplication::focusWidget(), event2);} );
    

    The code for QActions is complex so I am glad I don't have to find things there and run the triggers.
    @SGaist I thought about that but it was creating an empty dialog, maybe I didn't implement it properly.

    In any case now this is working as expected, thank you both very much.


  • Qt Champions 2016

    @danividanivi
    Ok super.
    To sleep good at night, i think i would check that correct widget have focus
    before sending enter to avoid some day it might find the close dialog button or something later on :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.