无模式 Qt window 在 parent 之上,但不在其他应用程序之上
Modeless Qt window on top of parent, but not on top of other applications
我希望有一个 Qt 对话框 window:
- 始终保持在其 parent(主应用程序 window)之上,
- 允许用户与 parent window 和
进行交互
- 并不总是位于其他应用程序之上。
我已经能够通过使对话框成为模态来实现 1 和 3,并且我可以通过使用 Qt::WindowStaysOnTopHint window 标志来实现 1 和 2。但我无法同时完成这三项工作 - 可能吗?
如果答案是 OS-specific,我主要研究 Mac,但我更喜欢同样适用于 Windows 和 Linux 的解决方案。谢谢!
默认的 QWidget 足以满足您的需求。
如果您创建的 QWidget 具有主窗口的父级,它将位于其他小部件之上。您只需要最后创建它或使用 QWidget::raise().
正确堆叠它
您可以尝试将 QGuiApplication::applicationStateChanged
. This way you get notified if the user enters or leaves your application. Just dynamically add and remove the Qt::WindowStaysOnTopHint
flag for your window. If you have multiple windows, you can use QGuiApplication::focusWindowChanged
与第一个一起使用。
编辑: 要使对话框成为非模态对话框,请将 NULL
设置为其父级,或将 windowModality-属性 设置为 Qt::NonModal
并使用 show
而不是 open
或 exec
显示对话框
QDialog 子类中的示例代码:
connect(QApplication::instance(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(changeAlwaysOnTop(Qt::ApplicationState)));
...
void MyDialog::changeAlwaysOnTop(Qt::ApplicationState state)
{
if (state == Qt::ApplicationActive)
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
else
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
show();
}
我知道我已经发布了一个答案,但我找到了最好的解决方案:
使用QDockWidget
。 DockWidget 将始终位于其父级之上,如果您将 allowedAreas
属性 设置为 Qt::NoDockWidgetArea
,window 将按您需要的方式运行!
此 window 将始终位于最前面:
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowStaysOnTopHint)
或者您可以传递现有的标志:
self.setWindowFlags( self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
只有当 QDialog 是使用 NULL 父对象创建时,我才能重现原始问题。否则,以下几行足以满足要求 1、2 和 3。
dlg=new MyDialog(applicationMainWidget);
dlg->show();
我希望有一个 Qt 对话框 window:
- 始终保持在其 parent(主应用程序 window)之上,
- 允许用户与 parent window 和 进行交互
- 并不总是位于其他应用程序之上。
我已经能够通过使对话框成为模态来实现 1 和 3,并且我可以通过使用 Qt::WindowStaysOnTopHint window 标志来实现 1 和 2。但我无法同时完成这三项工作 - 可能吗?
如果答案是 OS-specific,我主要研究 Mac,但我更喜欢同样适用于 Windows 和 Linux 的解决方案。谢谢!
默认的 QWidget 足以满足您的需求。
如果您创建的 QWidget 具有主窗口的父级,它将位于其他小部件之上。您只需要最后创建它或使用 QWidget::raise().
正确堆叠它您可以尝试将 QGuiApplication::applicationStateChanged
. This way you get notified if the user enters or leaves your application. Just dynamically add and remove the Qt::WindowStaysOnTopHint
flag for your window. If you have multiple windows, you can use QGuiApplication::focusWindowChanged
与第一个一起使用。
编辑: 要使对话框成为非模态对话框,请将 NULL
设置为其父级,或将 windowModality-属性 设置为 Qt::NonModal
并使用 show
而不是 open
或 exec
QDialog 子类中的示例代码:
connect(QApplication::instance(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(changeAlwaysOnTop(Qt::ApplicationState)));
...
void MyDialog::changeAlwaysOnTop(Qt::ApplicationState state)
{
if (state == Qt::ApplicationActive)
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
else
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
show();
}
我知道我已经发布了一个答案,但我找到了最好的解决方案:
使用QDockWidget
。 DockWidget 将始终位于其父级之上,如果您将 allowedAreas
属性 设置为 Qt::NoDockWidgetArea
,window 将按您需要的方式运行!
此 window 将始终位于最前面:
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowStaysOnTopHint)
或者您可以传递现有的标志:
self.setWindowFlags( self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
只有当 QDialog 是使用 NULL 父对象创建时,我才能重现原始问题。否则,以下几行足以满足要求 1、2 和 3。
dlg=new MyDialog(applicationMainWidget);
dlg->show();