PDA

View Full Version : how to catch keyPressEvents on Widgets when MainWindow is hidden



daniel.ste
31st October 2018, 09:23
Hi all,

I'm working on a QtWidgets (Qt 5.11) based Desktop Application on Mac OS.

The MainWindow creates a custom QWidget that reimplements keyPressEvent:



void QuickInterface::keyPressEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_Up)
{
qDebug() << "Up pressed";
emit editorSelected();
}
else if(event->key() == Qt::Key_Down)
{
qDebug() << "Down pressed";
}
else if(event->key() == Qt::Key_Left)
{
qDebug() << "Left pressed";
}
else if(event->key() == Qt::Key_Right)
{
qDebug() << "Right pressed";
}
else if(event->key() == Qt::Key_Escape)
{
qDebug() << "Escape pressed";
}
}


The code is working as expected unless the MainWindow is minimized to the tray. Although the widget is still showing normal and has Focus and the qApplication is the currently active Desktop Application the KeyEvents are being ignored.

Any ideas on what I could be missing? I don't understand the reason for this dependency. Can I change this behavior somehow, maybe by reimplementing the showMinimized() Slot of QMainWindow?

d_stranz
31st October 2018, 16:23
The MainWindow creates a custom QWidget that reimplements keyPressEvent

Is this widget created as a child of MainWindow (that is, do you pass a MainWindow pointer in to its constructor)? If so, try creating it as a top-level widget (e.i. with no explicit parent).

daniel.ste
5th November 2018, 19:36
Is this widget created as a child of MainWindow (that is, do you pass a MainWindow pointer in to its constructor)? If so, try creating it as a top-level widget (e.i. with no explicit parent).

Hi, sorry for my late reply!

It didn't make any difference, but I found the problem myself. I had set Qt::Popup WindowFlag for the Widget (sorry for not posting the code, forgot about it). Qt::Popup makes the Widget hide when it looses focus (by clicking outside).

Unfortunately it also makes the Widget ignore KeyPressEvents when the MainWindow is minimized.

You can reproduce it:

Create a new QtCreator project. Create a custom widget (HotKeyWidget) and reimplement keyPressEvent like this.


void HotKeyWidget::keyPressEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_Down)
{
qDebug() << "Down pressed -> MainWindow minimized";
emit minimizeMainWin(); // define signal in header

} else if(event->key() == Qt::Key_Left)
{
qDebug() << "Left pressed -> Widget WindowFlag Qt::Popup set";
this->setWindowFlag(Qt::Popup); // setting the window flag initially hides the window (intended?)
this->showNormal(); // show the widget again
}
else
qDebug() << "KeyPressEvent";
}

In the MainWindow constructor:


this->setWindowTitle("MainWindow");
HotKeyWidget *hkWidget = new HotKeyWidget(); // making this a child doesn't change behavior
QObject::connect(hkWidget, SIGNAL(minimizeMainWin()), this, SLOT(showMinimized()));
hkWidget->setWindowTitle("hkWidget");
hkWidget->showNormal();

1. Run the application and bring MainWindow and Widget to front. Click Widget to set Focus
2. Press any key to see KeyPressEvent Debug Message. (Works as expected)
3. Press Down Key to minimize MainWindow.
4. Press any key to see KeyPressEvent Debug Message. (Works as expected even if MainWindow is minimized)
5. Show MainWindow normal (unminimize) and click Widget again to set focus.
6. Press Left Key to set Qt:Popup WindowFlag to the widget.
7. Press any key to see KeyPressEvent Debug Message. (Works as expected even if Qt:Popup is set)
8. Press Down Key to minimize MainWindow again.
9. Press any other key and see KeyEvents are being ignored.

So it turns out that the combination of setting Qt::Popup WindowFlag to the Widget and minimizing MainWindow makes the Widget ignore KeyEvents. Looks like a bug doesn't it? Did not test it on windows yet.