禁用为按钮设置可检查 QPushbutton 的背景颜色

Posted

技术标签:

【中文标题】禁用为按钮设置可检查 QPushbutton 的背景颜色【英文标题】:Setting background-color of a checkable QPushbutton for button is disabled 【发布时间】:2021-03-21 16:31:16 【问题描述】:

我尝试设置pushButton.checked()的背景颜色。如果按钮被启用并且pushButton.checked() == False 工作正常,它将背景颜色设置为styleSheet()disabled 颜色但是如果按钮被禁用并且pushButton.checked() == True 它不会改变背景颜色。 我已经尝试了this post 中的解决方法,但没有运气。其他一些靠近帖子链接。

下面的示例:使用下部按钮启用(禁用上部并使用上部按钮将其设置为选中/取消选中并使用下部按钮启用/禁用它以了解我的意思。背景应始终将其灰色按钮已禁用。

是否需要特殊设置或组合?

import sys

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setMinimumSize(300,300)
        self.pushButton1 = QPushButton("see css result", self)
        self.pushButton1.setCheckable(True)
        #self.pushButton1.setAutoFillBackground (True)    # mentioned in
        self.pushButton1.setStyleSheet(css_pushButton())
        self.pushButton1.resize (100, 40)
        self.pushButton1.move(50,50)
        print("scc1:", self.pushButton1.styleSheet())

        self.pushButton_control = QPushButton("Button Enabled", self)
        self.pushButton_control.setCheckable(False)
        self.pushButton_control.clicked.connect(self.pushButton_control_clicked)
        self.pushButton_control.move(50,100)
        self.pushButton_control.resize (100, 40)

    def pushButton_control_clicked(self):
        print("Checked:",self.pushButton1.isChecked())
        if self.pushButton1.isEnabled():
            print("set False")
            self.pushButton1.setEnabled(False)
            self.pushButton_control.setText(('DISABLED'))
        else:
            self.pushButton1.setEnabled(True)
            self.pushButton_control.setText(('ENABLED'))
            print("set True")


def css_pushButton():
    css = '''
            QPushButton 
                            font-size: 10px;
                            background-color: green;
                            color: black;
                            border: 2px green;
                            border-radius: 22px;
                            border-style: outset;
                                
            QPushButton:hover 
                            background: qradialgradient(
                                cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4,
                                radius: 1.35, stop: 0 grey, stop: 1 lightgray
                                );
                            
            QPushButton:enabled
                            color: black;
                            font:  10px;
                            background: green;
                            background-color: red;
                            border: 1px black;
                            border-style: outset;
                            
            QPushButton:pressed 
                            color: white;
                            background: yellow;
                            
            QPushButton:disabled 
                            color: gray;
                            background-color: gray;
                            border: 1px black;
                            border-style: outset;                
                        
            QPushButton:checked
                        color: black; 
                        font:  12px;   
                        font: bold;
                        background-color: red;
                        border: 1px black;
                        border-style: outset;
                        
            QPushButton:!checked
                        color: black; 
                        font:  12px;   
                        font: bold;
                        background-color: green;
                        border: 1px black;
                        border-style: outset;
            
            
                '''
    return css

if __name__ == "__main__":
    app = QApplication (sys.argv)
    prog = MainWindow()
    prog.show ()
    app.exec_ ()

【问题讨论】:

【参考方案1】:

即使在 OOP 中,对象和属性声明的顺序 也很重要,因为最后一个优先于前一个。这对样式表也有效。

在您的代码中,:checked:!checked 规则优先于(“覆盖”)之前声明的任何属性,包括在 :disabled 中指定的属性。

解决方案很简单:将:disabled 块移到末尾。

更好的是,使用组合选择器:

            QPushButton:disabled 
                        color: gray;
            
            QPushButton:disabled:checked 
                        background-color: #ffaaaa;
            
            QPushButton:disabled:!checked 
                        background-color: lightGreen;
            

在 Qt 文档中了解更多关于 stylesheet conflict resolution 的信息。

【讨论】:

我认为disabled 和所有其他键是独立的属性并且不相互依赖所以我没有注意它。但是这个组合非常有用,我直到现在才使用它。 @Papageno 考虑这个样式表:QWidget background: green; QWidget background: red; 。这是一个有效的语法,但背景会有什么颜色?样式表是一个覆盖对象属性的系统,在 cascade 中:任何选择器都用于设置更多 特定 属性,如果没有明确指定,则继承默认属性。它与标准样式表的工作方式类似,而 Qt 只是实现了相同的行为。 它看起来很简单,听起来很合乎逻辑。但是测序的定义在哪里?正如我在示例中提到的那样,它可能是!checked > checked > disabled > pressed > enabled > hover > basic settings。根据我的经验,最好填写所有使用过的parameter : values;,但我仍在寻找层次结构。我认为层次结构是由css的结构构成的,但它是如何在内部上升的?如果我是对的,你提到的背景应该是红色的。 为每个选择器(包括子控件和伪状态)设置 all 属性并不总是一件好事。首先,你可能会写很多不必要的代码(例如,你的边框几乎总是 1px 黑色);然后你将覆盖依赖于其他选择器的属性:在checked 伪状态上设置边框会覆盖之前为任何其他伪状态设置的任何边框,只要检查小部件。是的,在我之前评论的例子中,结果是背景是红色的。请记住,您也可以将属性用作选择器: 例如,如果您希望始终将border: 2px green; 用于普通的可点击 按钮,而将border: 1px black; 用于可检查 按钮,那么您可以使用QPushButton border: 2px green; QPushButton[checkable="true"] border: 1px black;

以上是关于禁用为按钮设置可检查 QPushbutton 的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

Pyqt5_QPushButton

可拖动按钮时如何将单击事件设置为禁用?

(Qt C++) QPushButton setIcon() 不工作

设置 Qt QPushButton 弹出菜单的位置(向右)

找出是不是使用 self.sender() 检查 PyQt QPushButton

更改按钮文本时如何自动更改 QPushButton 宽度和 QMenuBar 角小部件宽度?