非模态QWidget对话框,始终置于窗口顶部。

6
我希望有一个对话框能够始终显示在我的主窗口之上,而不是其他窗口。我派生了一个类并添加了一些标志。如果我现在使用show()调用对话框,则该对话框将出现并且会一直保持在顶部,直到我按下按钮或其他操作。然后对话框再次进入后台。
Dial::Dial(QWidget *parent) : QWidget(parent) 
{
  this->setWindowFlags(Qt::Tool | Qt::Dialog);
  // ...

因此,我查看了文档并找到了以下内容:

表示小部件是工具窗口。工具窗口通常是带有比通常更小的标题栏和装饰的小窗口,通常用于工具按钮的集合。如果有父级,则工具窗口将始终保持在其上方。

幸运的是,我将此行添加到创建对话框的单例中。
d->mainWindow = new Foo();
d->dial->setParent(d->mainWindow);

现在对话框只是嵌入到我的中央小部件 (QOpenGlWidget) 中,不再是对话框了。但我似乎缺乏理解文档的能力?如何使对话框保持在应用程序的顶部,文档又是什么意思?

enter image description here


你为什么要使用 QWidget 而不是 QDialog - msrd0
QDialog的行为基本相同。我刚刚测试过了。 - dgrat
1
没有一种平台无关的方法来实现这个。在我上一个工作中,我花了很多时间试图找到解决这个问题的办法。 你可以通过一些窗口标志和类似的组合在Windows上实现这个效果,但使用一些不同的窗口标志在Mac上并不能得到正确的效果。而且在Mac上的行为还取决于操作系统的版本。如果你可以接受弹出窗口在应用程序失去焦点时消失,并在获得焦点时重新出现,那么可以使用窗口标志来实现。 - SteakOverflow
很遗憾,我已经预料到这个问题没有“干净”的解决方法。 - dgrat
4个回答

5
我无法重现您的问题。以下代码将生成一个 QWidget,它将始终保持在 QMainWindow 的顶部:
#include "QApplication"
#include "QMainWindow"
#include "QLineEdit"
int main(int argc, char * argv[])
{
    QApplication a(argc, argv);

    QMainWindow w;
    w.show ();

    QWidget *pLineEdit = new QWidget(&w);
    pLineEdit->setWindowFlags(Qt::Tool | Qt::Dialog);
    pLineEdit->show ();

    a.exec ();
}

已在Qt 5.9上进行测试。


好的,它保持在最前面。只要我不使用它。在对话框上按下一个按钮并转到主窗口后,它直接跑到所有窗口的后面。至少在Windows上是这样。没有在Linux上测试过。 - dgrat
兄弟!你今天救了我的工作。感谢你的提示,它对我非常有效。 - Israeldev

2

不确定您是否已经解决了这个问题,但是在构建对话框时,您可以尝试使用WindowStaysOnTopHint标志:

Qt::WindowFlags flags = this->windowFlags();
flags |= Qt::WindowStaysOnTopHint;
this->setWindowFlags(flags);

然后使用show()代替exec(),使其非模态:
dlg->show();

1
你需要设置小部件的模式(文档),像这样:
QWidget *dialog = new QWidget(window, Qt::Dialog);
dialog->setWindowModality(Qt::ApplicationModal);
dialog->show();

不过,我建议使用预配置的 QDialog 类,它会为您处理所有相关内容:

QDialog *dialog = new QDialog(window);
dialog->exec();

1
如果我使用这个,对话框会阻止主窗口的所有输入事件。有没有可能是Qt系统出了问题,因为它似乎对非模态对话框不起作用? - dgrat
不,那只是它的工作方式。我只是在一个非常简单的窗口中运行该代码,每次我在窗口本身移动鼠标时,它就会移动到对话框中,但我可以将其他窗口置于其上方。 - msrd0
有没有一种方法可以实现非模态对话框? - dgrat
我刚刚仔细阅读了qdialog的所有窗口标志和源代码,但除了模态之外,我没有找到任何可以使窗口保持在另一个窗口之上的内容。 - msrd0

1
使用QDialog代替QWidget,并在其构造函数中传递父部件
QDialog* pDlg = new QDialog(this);
pDlg->show();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接