首页 > 解决方案 > pyqt5 总是在顶部单选按钮不起作用

问题描述

我使用 pyqt5 python 制作了 Always on top 单选按钮。

但不工作,没有错误。有什么问题?

单击单选按钮时,将字符串(“ON”或“OFF”)传递给func

def radioButtonClicked_always始终在顶部代码上作为字符串执行

"ON" = 始终在顶部执行 "OFF" = 始终在顶部禁用

我添加print("ON")测试。它也可以正常工作。

import sys, os
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class Button(QWidget):

    def __init__(self, parent):
        super(Button, self).__init__(parent)
        self.parent = parent
        self.initUI()

    def initUI(self):
        listBox = QVBoxLayout(self)
        self.setLayout(listBox)

        listBox.addStretch(1)

        hbox = QHBoxLayout()
        group_box_2 = QGroupBox("Always on Top")
        hbox.addWidget(group_box_2)
        hbox_in = QHBoxLayout()
        group_box_2.setLayout(hbox_in)

        rb2_1 = QRadioButton("ON")
        rb2_1.clicked.connect((lambda state, x=rb2_1.text(): self.radioButtonClicked_always(x)))
        hbox_in.addWidget(rb2_1)

        rb2_2 = QRadioButton("OFF")
        rb2_2.clicked.connect((lambda state, x=rb2_2.text(): self.radioButtonClicked_always(x)))
        rb2_2.setChecked(True)
        hbox_in.addWidget(rb2_2)
        listBox.addLayout(hbox)

        self.setWindowTitle('Helper')
        self.setGeometry(300, 300, 300, 200)
        # self.show()

    def radioButtonClicked_always(self, s_state):
        if s_state == "ON":
            print("ON")
            self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
        else:
            print("OFF")
            self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)

    def closeEvent(self, event):
        self.deleteLater()


class MyApp(QMainWindow):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.statusBar().showMessage('Ready')

        bt = Button(self)
        self.setCentralWidget(bt)
        self.setGeometry(300, 300, 300, 200)
        self.show()

    def closeEvent(self, event):
        self.deleteLater()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyApp()
    sys.exit(app.exec_())

标签: pythonpython-3.xpyqtpyqt5

解决方案


您正在为子小部件“Button”设置窗口标志(顺便说一下,我建议您使用另一个名称),而您必须为window设置它。

此外,作为有关windowFlags报告的文档:

注意:此函数在更改窗口的标志时调用 setParent(),导致窗口小部件被隐藏。您必须调用 show() 使小部件再次可见..

因此,您必须为小部件的顶级窗口(可通过 访问QWidget.window())设置标志,并在此之后立即调用窗口的 show() 方法。


    def radioButtonClicked_always(self, s_state):
        if s_state == "ON":
            print("ON")
            self.window().setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
        else:
            print("OFF")
            self.window().setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)

        self.window().show()


请注意,您不应使用小部件的标签进行比较。对于类似的情况,请改用QButtonGroup:您可以为添加的每个按钮设置一个 ID,并使用该 ID 来识别哪个按钮已被切换。

考虑到buttonToggled未选中按钮时也会发送信号,因此您必须同时检查选中状态按钮 ID,并且在您的情况下,仅在选中状态为 True 时设置窗口标志。

class Button(QWidget):
        # ...
    def initUI(self):
        listBox = QVBoxLayout(self)
        self.setLayout(listBox)

        listBox.addStretch(1)

        hbox = QHBoxLayout()
        group_box_2 = QGroupBox("Always on Top")
        hbox.addWidget(group_box_2)
        hbox_in = QHBoxLayout()
        group_box_2.setLayout(hbox_in)

        rb2_1 = QRadioButton("ON")
        hbox_in.addWidget(rb2_1)

        rb2_2 = QRadioButton("OFF")
        rb2_2.setChecked(True)
        hbox_in.addWidget(rb2_2)
        listBox.addLayout(hbox)

        buttonGroup = QButtonGroup(self)
        buttonGroup.addButton(rb2_1, 1)
        buttonGroup.addButton(rb2_2, 0)
        buttonGroup.buttonToggled[int, bool].connect(self.setOnTop)

        self.setWindowTitle('Helper')
        self.setGeometry(300, 300, 300, 200)

    def setOnTop(self, buttonId, status):
        if not status:
            return
        if buttonId:
            self.window().setWindowFlags(
                self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
        else:
            self.window().setWindowFlags(
                self.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)
        self.window().show()

推荐阅读