通过复选框 PyQt 始终处于最前面的行为

Always on top behavior through a check box PyQt

关于"always on top"问题的资料很多,但我经验不足,看不懂。 我想在我的 window(即 QDialog)上有一个 CheckBox(aboveAll)来将 window 的行为从 'normal' 切换到 'always on top'。我得到的最接近的:

from PyQt4.QtGui import *
class MyForm(QtGui.QDialog):
    def __init__(self, parent = None):
        QtGui.QWidget.__init__(self,parent)
        self.ui = Ui_Kamipy()
        self.ui.setupUi(self)
        self.ui.aboveAll.stateChanged.connect(self.ABOVE)
    def ABOVE(self):
        if self.ui.aboveAll.isChecked() == True:
            self.ui.setWindowFlags(self.ui.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)
        if self.ui.aboveAll.isChecked() == False:
            self.ui.setWindowFlags(self.ui.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)

并带来以下错误:

Traceback (most recent call last): File "kamimimi.pyw", line 17, in ABOVE self.ui.setWindowFlags(self.ui.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) AttributeError: 'Ui_Kamipy' object has no attribute 'setWindowFlags'

是不是因为我的window是对话框(不是主window)?我该如何解决?

您的window一个对话框。但是您没有调用 window 的方法;您正在调用 self.ui 的方法 - 正如回溯告诉您的那样,它属于 Ui_Kamipy 类型,而不是 QDialog.

self.ui 对象只是一个简单的 python 包装器 class,它为您在 Qt Designer 中添加的小部件提供名称空间。当你调用它的 setupUi 方法时,你传入了一个你在 Qt Designer 中创建的顶层 class 的实例。所以在这种情况下,顶层class是QDialog,你传入实例self.

所以 window 是 self,它的子控件可以作为命名空间 self.ui 的属性访问。这意味着您的代码应该更像这样:

from PyQt4 imort QtCore, QtGui

class MyForm(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.ui = Ui_Kamipy()
        self.ui.setupUi(self)
        self.ui.aboveAll.stateChanged.connect(self.ABOVE)

    def ABOVE(self):
        if self.ui.aboveAll.isChecked():
            self.setWindowFlags(
                self.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)
        else:
            self.setWindowFlags(
                self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
        self.show()

请注意,我在底部添加了行 self.show(),因为 setWindowFlags 会导致 window 隐藏。