Question

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;
    }
Was it helpful?

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() );

OTHER TIPS

When a widget does not handle an event, it forwards it to its parent. So using sendEvent() to forward to a child is dangerous, as it can make a recursion.

The easiest way of doing it would be to use QKeyEvent::text instead of QKeyEvent::key and you should be OK. You might also try to create a copy of QKeyEvent and pass it to your QLineEdit. Thos are rather hacks than solutions though. If you need shortcuts in main window while QLineEdit has focus (assuming it is in this window) you can use QShortcut with Qt::WidgetWithChildrenShortcut context - this way you can keep your LineEdit active at all times.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top