Search code examples
c++qtsendkeys

How to send key to parent mainWindow from dialog in QT C++


I need a virtual keyboard for an embedded linux application (not QML). I couldn't find a better way, so now I am trying to create one. I want a dialog full of buttons that sends keys to parent mainWindow. It runs without errors, but happens nothing in lineEdit.

keyboard.cpp

Keyboard::Keyboard(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Keyboard)
{
    ui->setupUi(this);
    mainWindow = this->parent();
}

void Keyboard::on_btnA_clicked()
{
    qDebug() << "Test1";
    QKeyEvent event(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier);
    qDebug() << "Test2";
    QApplication::sendEvent(mainWindow, &event);
    qDebug() << "Test3";
}

And in mainWindow.cpp to open keyboard dialog:

  keyboard->show();
  ui->lineEdit->setFocus();

What is the problem? Thanks in advance.


Solution

  • Several things:

    1. Sending the event to mainWindow requires mainWindow to handle passing the event to the QLineEdit object, without seeing the rest of the code I can't say if this is being done or not; the alternative is sending directly to the QLineEdit like this:

      QApplication::sendEvent(lineEdit, &event);
      


    2. The QKeyEvent constructor also requires a fourth parameter - the string to send, in the example case an "a".

      QKeyEvent event(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier);
      

      should be

      QKeyEvent event(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "a");
      

      to send an "a".


    1. Depending on the exact implementation you may also need to send a QEvent::KeyRelease after the QEvent::KeyPress, i.e.

      QKeyEvent event1(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "b");
      QKeyEvent event2(QEvent::KeyRelease, Qt::Key_A, Qt::NoModifier);
      QApplication::sendEvent(edit, &event1);
      QApplication::sendEvent(edit, &event2);
      


    2. As (2) indicates, the key enumeration (i.e. Qt::Key_A) does not send an "a" as you would expect, the string that is sent is instead determined by the fourth parameter in the QKeyEvent constructor, i.e.

      QKeyEvent event(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "a");
      QApplication::sendEvent(lineEdit, &event);
      

      Is equivalent to

      QKeyEvent event(QEvent::KeyPress, Qt::Key_B, Qt::NoModifier, "a");
      QApplication::sendEvent(lineEdit, &event);
      


    1. Using QKeyEvent in this manner will probably lead so some unpleasantness in handling backspaces and deletes. It is probably more elegant to simply append the desired character to the QLineEdit text,

      lineEdit->setText(lineEdit->text().append("a"));
      

      and use QLineEdit::backspace() and QLineEdit::delete() to handle backspace and delete keys.


    Example

    #include <QtWidgets/QApplication>
    #include <qwidget.h>
    #include <qmainwindow.h>
    #include <qlineedit.h>
    #include <qboxlayout.h>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QMainWindow* main = new QMainWindow;
        QWidget* central = new QWidget();
        QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight);
        central->setLayout(layout);
        QLineEdit* edit = new QLineEdit(central);
        edit->setAlignment(Qt::AlignCenter);
        layout->addWidget(edit);
    
        edit->setText("sometext");
        edit->backspace();
        edit->setText(edit->text().append("a"));
    
        main->setCentralWidget(central);
        main->resize(600, 400);
        main->show();
    
        return a.exec();
    }