Pyside6 .qss 文件导致切换按钮在单击后才调整大小

问题描述 投票:0回答:1

我正在尝试制作一个切换按钮,当您单击它时,它可以简单地从锁定符号切换到解锁符号。

对于我的主程序,我有一个 .qss 文件,它将默认样式表应用于程序中的一堆小部件。当我不使用这个 .qss 文件时,我的程序运行正常。但是,当我应用 .qss 文件时,切换按钮会占据普通按钮的大小,直到您单击该按钮一次。

示例:

Top 4 buttons have been clicked once

如您所见,顶部按钮我点击过一次,但底部按钮要大得多。如果我不使用 .qss 文件,按钮将默认为预期的小尺寸。

我尝试将

self.setstylesheet("")
添加到 Toggle_Button 所以它不会 来自 stylehseet 的 inharent(现在仍然如此)

我的切换按钮代码如下所示:

class ToggleButton(QPushButton):
    def __init__(self):
        super().__init__()
        #get image paths:
        self.locked = "Locked_Clipart.png"
        self.unlocked = "Un_Locked_Clipart.png"
        # Load the image and set it as the button icon
        self.setIcon(QIcon(self.locked))
        
        # Set the icon and button size to 32x32 pixels
        self.setIconSize(QSize(32, 32))
        self.setFixedSize(32, 32)

        self.setMinimumWidth(32)
        self.setMaximumWidth(32)
        self.adjustSize()
        
        # Optional: remove button border
        self.setStyleSheet("")

        #setup toggle
        self.setCheckable(True)
        self.toggled.connect(self.update_icon)
    
    def update_icon(self, checked):
        if checked == False:
            self.setIcon(QIcon(self.locked))
            
        else:
            self.setIcon(QIcon(self.unlocked))

        # Set the icon and button size to 32x32 pixels again (idk if this is needed)
        self.setIconSize(QSize(32, 32))
        self.setFixedSize(32, 32)

可以在此处找到所需的两个图像,但您也可以使用自己的图像: Locked Pic unlocked

我的基本示例可以在这里找到:

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout()

        # Layout to display the button
        count = 1
        while count < 10:
            button = ToggleButton()
            layout.addWidget(button)
            count += 1
        
        self.setLayout(layout)


app = QApplication([])
# Apply stylesheet
qss_path = "style.qss"

try:
    with open(qss_path, "r") as file:
        stylesheet = file.read()
except FileNotFoundError:
    print(f"Stylesheet not found at {qss_path}")
    stylesheet = ""

if stylesheet:
    app.setStyleSheet(stylesheet)

window = MainWindow()
window.show()
app.exec()

.qss 文件可以在这里找到:

QPushButton {
    background-color: rgb(0, 128, 200);
    color: white;
    border: 1px solid #000000;
    padding: 5px;
    border-radius: 4px;
    min-width: 85px;
    margin: 0px;
    height: 15px
}
QPushButton#Lock_Toggle {
    background-color: #f0f0f0;       /* Light gray background */
    color: black;                    /* Black text */
    border: 1px solid #a9a9a9;       /* Gray border */
    padding: 4px 8px;                /* Padding for button content */
    border-radius: 3px;    
}

QPushButton:hover {
    background-color: rgb(0, 164, 242);
}

QPushButton:pressed {
    background-color: rgb(79, 198, 255);
}
python stylesheet pyside6
1个回答
0
投票

Qt 样式表 (QSS) 的语法与属性管理及其声明并不总是一致,并且在样式表中设置对象属性时应始终小心,这可能与代码所做的不一致。
在这种特定情况下,样式表中的

min-size
属性与
setMinimumWidth()
调用完全相反。

虽然这可能被认为是一个错误,但您必须考虑到 Qt 样式可能优先于小部件的大小提示/限制。它从根本上“更新”属性,即使它是由纯代码设置的。当其中任何一个最终被应用时,总是可以预见的。

有不同的方法可以解决这个问题,主要取决于样式表,但也考虑小部件、对象和类层次结构。

如果您希望所有 QPushButton 都具有最小宽度,除了来自该特定子类,那么您只需要使用类选择器(请参阅QSS语法文档),这样只有 QPushButton 实例才会遵循该规则,而不是它的子类:

QPushButton {
    /*
        everything else *but* the min-width property
    */
}
.QPushButton {
    min-width: 85px;
}

另一个选择是,只要您完全确定该类显式设置了大小限制,就可以使用比代码中任何地方声明的值更小的值;最简单的解决方案是使用负值:

ToggleButton {
    min-width: -1;
}

注意:QSS 规范基于早期的 CSS 2.1,它不提供诸如

:not()
选择器之类的“否定”。

或者,您可以在子类中覆盖

changeEvent()
并再次强制固定大小,以防收到 StyleChange
 事件类型:

class ToggleButton(QPushButton): ... def changeEvent(self, event): super().changeEvent(event) if event.type() == event.Type.StyleChange: self.setFixedWidth(32)
最后:

    在布局管理的小部件中调用
  • adjustSize()
    是完全没有意义的,因为布局管理器的目的是
    管理布局(因此,在其小部件上调用setGeometry()
    ,这显然会覆盖之前调用
    adjustSize()的任何尝试)
    );
  • 正如文档清楚地解释的那样,
  • setFixedSize()
    设置
    both最小最大尺寸;使用与前一个 setMinimumWidth()
     相同的宽度值调用 
    setMaximumWidth()
    setFixedSize()
     是完全没有用的;
  • 在小部件的
  • setStyleSheet("")
     内调用 
    __init__
     是无用的,因为不合适,因为此时样式表无论如何都是空的,并且还强制完全不必要的递归样式计算;
© www.soinside.com 2019 - 2024. All rights reserved.