Search code examples
qtfocussetfocusqt4.7qlineedit

silently transfer keyPressEvent to one child , and make it focus?


When user types in a QWidget based window, I wanted a QLineEdit to process all input keys, so I tried the following two solution in keyPressEvent() of that QWidget:

A.

void Window::keyPressEvent (QKeyEvent *e)
{
   switch (e->key())
   {
     // handle other short cuts
     default:
       QApplication::sendEvent (lineEdit , e);
       break;
   }
}

Well, this sometimes crashes the whole interface, especially when I resize window.

B.

void Window::keyPressEvent (QKeyEvent *e)
{
   switch (e->key())
   {
     // handle other short cuts
     default:

     if ( ! lineEdit.hasFocus () )
     {
        lineEdit.setFocus ();
        lineEdit.setText (e->key()); 
        // i wanted to push the first key input to that QLineEdit , but how ?
        // or i'll miss it
     }
     break;
   }
}

Also I'm thinking about giving lineEdit focus all the time, but I can't do that as other events needed to be handled by the main UI.

Update

It won't crash when I filter key inputs, but why ?

 default:
        if ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete ||
                (e->key() >= Qt::Key_A && e->key() <= Qt::Key_Z )
                )
            QApplication::sendEvent(filter , e);
        break;
    }

Solution

  • I believe you are running into a crash because you are using sendEvent to send an event object that you don't have control over.

    I don't think the Qt event system expects you to grab its events and throw them in other directions, and it's likely that the event object is getting destroyed before the line edit expects. In the case where you're filtering out input keys, it's probably not crashing because the line edit doesn't care about those kinds of key strokes and isn't using the event object as much as it would otherwise.

    If you really want to use the sendEvent() functionality, then I would suggest you create your own QKeyEvent on the stack and pass it to the sendEvent() function (as demonstrated here), or you can just do something like this:

    lineEdit.setText( lineEdit.text() + event->text() );