LXSession 上的 Qt4 WindowsStayOnTop

Posted

技术标签:

【中文标题】LXSession 上的 Qt4 WindowsStayOnTop【英文标题】:Qt4 WindowsStayOnTop on LXSession 【发布时间】:2020-01-22 21:33:27 【问题描述】:

我正在使用 qt4 的树莓派上运行一个应用程序。我的应用程序有不同的窗口、主窗口和对话框。当我在树莓派桌面上运行我的应用程序时,它工作正常,如果我点击主窗口,对话框不会结束在主窗口后面。

Qt.WindowStaysOnTopHint 工作正常。 Qt.WindowStaysOnTopHint 确保窗口位于主窗口的顶部,并且不会最终无法访问它。

当我在 lxsession 上运行我的应用程序时,自动启动

Qt.WindowStaysOnTopHint

工具不起作用...

知道如何解决吗?

到目前为止我所做的是调用

Dialog.setWindowFlags(Qt.WindowStaysOnTopHint|Qt.X11BypassWindowManagerHint) 

它有点工作,但对话框是无框的。

class Ui_MainWindow(object):

  def setupUi(self, MainWindow):
       MainWindow.setObjectName(_fromUtf8("MainWindow"))
       MainWindow.resize(800, 480)
       MainWindow.setMinimumSize(QtCore.QSize(800, 480))
       MainWindow.setMaximumSize(QtCore.QSize(800, 480))
       MainWindow.setWindowFlags(Qt.FramelessWindowHint)

class ControlMainWindow(QtGui.QMainWindow):

   def __init__(self, parent=None):
      super(ControlMainWindow, self).__init__(parent)
      self.ui = Main_Window.Ui_MainWindow()
      self.ui.setupUi(self)

以上是我的主窗口设置

下面是我的对话框设置,我从 MainWindow 调用它来显示。

class Ui_Dialog(object):

   def setupUi(self, Dialog):

    Dialog.setObjectName(_fromUtf8("Dialog"))
    Dialog.resize(492, 200)
    Dialog.setMinimumSize(QtCore.QSize(492, 200))
    Dialog.setMaximumSize(QtCore.QSize(492, 200))
    Dialog.setWindowFlags(Qt.WindowStaysOnTopHint)


class ControlMainDialog(QtGui.QDialog):

def __init__(self, parent=None):
    super(ControlMainDialog, self).__init__(parent)

    self.ui = Ui_Dialog()
    self.ui.setupUi(self)

我正在将 Dialog 或 ControlMainDialog 中的父级设置为:

Dialog.setParent(Qt.QMainWindow) 

这不正确,有什么想法吗?

【问题讨论】:

您是否在对话框初始化时设置了父级,还是仅使用留在顶部提示? 对话框初始化时没有设置parent,应该是*Dialog.setParent(MainWindow)"之类的吧?我马上试试! 不起作用,不确定如何设置父级,认为如果我初始化主窗口父级应该是正确的......可能需要找到一些关于这个的文档...... window modality of a QDialog 需要父实例。我真的认为你的实现方式有问题,你最好给我们一个minimal, reproducible example我们可以帮助你。 我的错,我添加了我的代码的最小示例。我希望它能让我知道我想要做什么。 【参考方案1】:

模态对话框需要一个父实例

删除Dialog.setWindowFlags(Qt.WindowStaysOnTopHint)(这将重置其他重要的窗口标志,例如Qt.Dialog标志);首先创建主窗口,然后创建对话框主窗口实例作为父窗口。

app = QtGui.QApplication(sys.argv)
mainWindow = ControlMainWindow()
mainWindow.show()
dialog = ControlMainDialog(mainWindow)
dialog.exec_()
sys.exit(app.exec_())

setParent 即使在对话框初始化后也可以使用,但它总是需要一个父窗口小部件实例。在QDialog documentation 中阅读更多内容。

【讨论】:

这是一个很好的解决方案,如果它重置了其他重要的标志,我会查看该文档甚至删除 setWindow 标志。我不明白在“Dialog.setParent()”中设置什么,它需要的小部件实例是 QMainWindow 小部件还是? 所有 QObject 后代(包括所有 QWidget,因此包括所有 QDialog)的父级必须始终是另一个 QObject 后代的实例。因此,如我的示例所示,在您的情况下,它必须是 mainWindow 实例,但可以是作为顶部窗口的任何其他 QWidget(不是已经是另一个窗口的 [子] 子窗口的小部件);通常最好在对象构造函数中设置父对象,大多数情况下,如果稍​​后再设置,它不会有太大变化,但这通常意味着子对象的某些属性可能会根据类发生变化。跨度> 我今天会再试一次。昨天我试图做 'Dialog.setParent(QMainWindow)' 并得到一个错误,令人困惑。我会做'Dialog.setParent(MainWindow)',这个MainWindow也应该被识别如果我从另一个文件调用/执行Dialog,ofc首先导入,对吗?我回家后会试试看,然后回来更新。 等等。你不能凭空“召唤”事物。它们是存在于其范围内的对象。这不仅仅是关于导入,它还取决于程序逻辑。很抱歉问,但您确定您了解类和实例之间的逻辑差异吗? 不不,它不是凭空出现的。我正在调用具有 Dialog 实例的类,这将执行它。我正在 Class 中进行 setParent 以及那里的所有配置。我只在另一个文件中执行对话框,而类和一个文件包含设置和配置。【参考方案2】:

我设法解决了这个问题,它实际上已在此处详细记录 [https://doc.qt.io/qt-5/qdialog.html#modal-dialogs]。当我想显示我的窗口时,我通过调用 show() 来使用无模式对话框,这允许我访问其他窗口并使对话框落后于主窗口,这是我的问题。 Using Modal dialog 是使用 exec() 显示的对话框,解释如下:

当打开应用程序模式对话框时,用户必须完成与对话框的交互并关闭它,然后才能访问应用程序中的任何其他窗口

【讨论】:

以上是关于LXSession 上的 Qt4 WindowsStayOnTop的主要内容,如果未能解决你的问题,请参考以下文章

Mac OS X 上的 Qt4Dotnet

SqlServer windowss身份登陆和sa身份登陆

qt4.6移植到qt4.7出现中文乱码

Qt入门之基础篇 ( 一 ) :Qt4及Qt5的下载与安装

Mac OS X 10.6(雪豹)上的 Qt 4.4 视觉伪影是不是有解决方法

如何在 Qt4 中将项目添加到模型并获取新添加项目的索引