Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Why it is impossible to simulate Key hold?



  • For the last few days i'm trying to make my app simulate keypress. First i went this trivial way:

    QKeyEvent *event = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_G, Qt::NoModifier, "A");
    QApplication::sendEvent(ui->textEdit, event);
    

    Btw i don't get that thing, what is the point specifying Qt::Key, if it'll take last QString parameter as desired "key" for pressing.

    Then i found QTest library, which have a shorter, nicer, but in fact completely the same function:

    QTest::keyPress(ui->textEdit,Qt::Key_T);
    

    And also tried windows.h SendInput function, which is nearly the same, with that difference that it can do keypress to the whole system, not only it's app windows/widgets.

    So none of that C++ functions with keyPress does not actually "press", they tap, click one single time, and that's it, so i came here with hope, that someone actually knows why it is impossible to simulate hold, like:

    QTest::keyPress(ui->textEdit,Qt::Key_T);
    QThread::sleep(4);
    QTest::keyRelease(ui->textEdit,Qt::Key_T);
    

    and get "tttttttttttttttttttttttt" instead of single t.

    And maybe even someone know the way how to simulate key hold.

    P.S. cycle tapping frequently in the loop many times not working since that will "rePress" button over and over, so to say, some LMButton can't press on some icon, and pull that aside, it'll loose that immediately.



  • it's platform dopendent at that point. look at the X11 events, which do in fact trigger both a press and release of a key. If you're using X11 then you can inject the key events using Xwindows.


  • Moderators

    @Engelard said:

    Btw i don't get that thing, what is the point specifying Qt::Key, if it'll take last QString parameter as desired "key" for pressing.

    Some letters take couple of keys to be formed. For example Polish letter ć is generated by pressing ALT+C. The first key press is for ALT (Qt::Key_Alt) which has empty text and then another keypress is for C (Qt::Key_C), but because ALT is still pressed the text is now "ć" instead of just "c".

    QThread::sleep(4);

    You need to use a timer to let the event loop going e.g. this works

    QTimer* t = new QTimer(ui->textEdit);
    t->setInterval(100);
    t->start();
    connect(t, &QTimer::timeout, ui->textEdit, [&]()
    {
        QKeyEvent evt(QKeyEvent::KeyPress, Qt::Key_G, Qt::NoModifier, "G");
        QApplication::sendEvent(ui->textEdit, &evt);
    });
    

    Also keep in mind that the next parameter after "G" is the autorepeat. If you're simulating a pressed and held key the first event should have autorepeat set to false and all the next ones to true until next key release event.



  • Both answers is good, thanks.


Log in to reply