PyQt5 保持 QWidget 始终在顶部

PyQt5 keep a QWidget always on top

当在我的主要 window 初始化函数中创建时,我可以强制子窗口小部件保持在顶部吗?

只有在应用程序范围内创建小部件时它才对我有用(如此处 )。

(在 Raspberry Pi OS 上测试)

from PyQt5 import QtCore
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QWidget
)

class Ui_MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setWindowTitle("MainWindow")
        self.resize(400, 300)
        Widget = Ui_Widget(self)
        Widget.show()

class Ui_Widget(QWidget):
    def __init__(self,  parent=None):
        QWidget.__init__(self, parent)
        self.setWindowFlags(self.windowFlags() | QtCore.Qt.Dialog)
        self.setWindowTitle("Widget")
        self.resize(400, 300)
        self.move(200, 150)

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    MainWindow = Ui_MainWindow()
    MainWindow.show()
    # Widget = Ui_Widget(MainWindow)
    # Widget.show()

    sys.exit(app.exec_())

该问题可能与 window 管理器中的某些错误或错误实施有关(在 Fluxbox 上它按预期工作)。

在任何情况下,为了保持一致性,您不应该在 显示父窗口小部件之前 显示父窗口小部件(假设两者必须同时出现):MainWindow.show() 处理 __init__ 之后调用 ,结果是您过早地显示了子窗口小部件。

一个基本的解决方法是在显示子窗口小部件之前调用 self.show(),但通常认为 显示窗口小部件(包括实例本身)是一种很好的做法__init__.

更好的解决方案是创建一个实际显示父窗口小部件的函数,然后然后创建并显示子窗口小部件:

class Ui_MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setWindowTitle("MainWindow")
        self.resize(400, 300)

    def start(self):
        self.show()
        Widget = Ui_Widget(self)
        Widget.show()

# ...

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    MainWindow = Ui_MainWindow()
    MainWindow.start()

    sys.exit(app.exec_())

请注意,对于 非常 的特定情况,通常需要为标准 QWidgets 使用 Dialog 标志。大多数时候,您可以只使用 QDialog 并调用 open() 而不是 show()。您还应该为子小部件创建一个持久引用,因为您可能需要从主 window class.
访问它 另请注意,名为 Ui_xyz 的 classes 通常用于基本 UI 形式(使用 pyuic/pyside-uic 创建的),并且变量名称不应大写,因为只有 classes 和常量使用此约定(更喜欢 mainWindow 而不是 MainWindow)。