Reputation: 93
My Qt5 desktop application shows a modal dialog right after showing the main window. The main window is shown as full screen with Qt::FramelessWindowHint
flag. The problem is when I close the dialog, the focus does not return to the main window. This is true for any dialog opened subsequently in the application.
A particular button on the main window is supposed to have focus and is set by calling QWidget::setFocus()
. But still the focus is not visible on that button (highlight with a different color on focus). I also observed that QApplication::activeWindow()
returns NULL at this point. The focus is seen only when an empty area of the main window is clicked with mouse. This makes it difficult to work with keyboard only.
There is no issue when deployed on Windows and Ubuntu and it works perfectly. But the problem is observed when deployed on Yocto Linux.
Yocto Linux is running without a Window Manager and Desktop Environment. Can this be an issue for the window not to get activated automatically?
Upvotes: 5
Views: 1031
Reputation: 10047
In such a situation (no window manager), the only workaround I can think of is using grabKeyboard
, e.g. in a slot where a QDialog
dialog is shown:
void MainWindow::on_pushButton_clicked()
{
/* ... */
dialog.exec();
grabKeyboard();
}
Please notice that without a window manager, there is no such thing as activation for top-level widgets, and decoration flags (like Qt::FramelessWindowHint
) make no sense as well.
In case this trick happens to work fine for your needs, you can resort to a function like this:
void showModalDialog(QDialog * dialog)
{
dialog->exec();
dialog->parentWidget()->grabKeyboard();
}
and use it whenever needed.
If the background widget isn't the dialog's parent, use an overload :
void showModalDialog(QDialog * dialog, QWidget * background)
{
dialog->exec();
background->grabKeyboard();
}
or mix it all in a single function:
void showModalDialog(QDialog * dialog, QWidget * background = nullptr)
{
dialog->exec();
if (background == nullptr)
{
background = dialog->parentWidget();
}
if (background != nullptr)
{
background->grabKeyboard();
}
}
If you fear (or experience) conflicts with the other platforms, have a #define
for yocto and wrap everything after the call to exec()
in the usual #ifdef
, e.g.
void showModalDialog(QDialog * dialog, QWidget * background = nullptr)
{
dialog->exec();
#ifdef YOCTO_LINUX
if (background == nullptr)
{
background = dialog->parentWidget();
}
if (background != nullptr)
{
background->grabKeyboard();
}
#endif
}
Upvotes: 2