我的 Qt5 桌面应用程序在显示主窗口后立即显示一个模式对话框。主窗口显示为带标志的全屏Qt::FramelessWindowHint。问题是当我关闭对话框时,焦点不会返回到主窗口。对于随后在应用程序中打开的任何对话框都是如此。
主窗口上的特定按钮应该具有焦点,并通过调用来设置QWidget::setFocus()。但该按钮上的焦点仍然不可见(焦点上用不同的颜色突出显示)。我还观察到QApplication::activeWindow()此时返回 NULL。仅当用鼠标单击主窗口的空白区域时才能看到焦点。这使得仅使用键盘工作变得困难。
在 Windows 和 Ubuntu 上部署都没有问题,完美运行。但是当部署在 Yocto Linux 上时,就会出现这个问题。
Yocto Linux 在没有窗口管理器和桌面环境的情况下运行。这会是窗口无法自动激活的问题吗?
在这种情况下(没有窗口管理器),我能想到的唯一解决方法是使用,例如在显示对话框grabKeyboard的插槽中:QDialog
void MainWindow::on_pushButton_clicked()
{
/* ... */
dialog.exec();
grabKeyboard();
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果没有窗口管理器,就没有顶级小部件的激活Qt::FramelessWindowHint之类的东西,并且装饰标志(如)也没有任何意义。
如果这个技巧恰好满足您的需求,您可以使用如下函数:
void showModalDialog(QDialog * dialog)
{
dialog->exec();
dialog->parentWidget()->grabKeyboard();
}
Run Code Online (Sandbox Code Playgroud)
并在需要时使用它。
如果背景小部件不是对话框的父级,请使用重载:
void showModalDialog(QDialog * dialog, QWidget * background)
{
dialog->exec();
background->grabKeyboard();
}
Run Code Online (Sandbox Code Playgroud)
或者将它们全部混合在一个函数中:
void showModalDialog(QDialog * dialog, QWidget * background = nullptr)
{
dialog->exec();
if (background == nullptr)
{
background = dialog->parentWidget();
}
if (background != nullptr)
{
background->grabKeyboard();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您担心(或经历)与其他平台发生冲突,请使用#definefor yocto 并将调用后的所有内容包装exec()在通常的 中#ifdef,例如
void showModalDialog(QDialog * dialog, QWidget * background = nullptr)
{
dialog->exec();
#ifdef YOCTO_LINUX
if (background == nullptr)
{
background = dialog->parentWidget();
}
if (background != nullptr)
{
background->grabKeyboard();
}
#endif
}
Run Code Online (Sandbox Code Playgroud)