【问题标题】:My PyQt5 Custom ScrollBar Stylesheet Doesn't apply我的 PyQt5 自定义滚动条样式表不适用
【发布时间】:2021-06-07 22:56:01
【问题描述】:

所以我在 PyQt5 中遇到了样式表问题。我试图为我的 QListWidget 制作一个自定义滚动条,它在 QtEditor 中运行良好,但在运行实际代码或在设计器中预览时不起作用。这是样式表:

QTableWidget{
    border-radius: 10px;
    background-color: transparent
}


QHeaderView::section{
    background-color:transparent;
    border-radius:10px;
}

QTableWidget::item{
    border-radius: 10px;
    background-color: rgb(92, 95, 141);
    margin-bottom: 3px;
    margin-right: 3px;
}


QTableWidget::item:selected{
    color: rgb(255, 255, 255);
    background-color: rgb(143, 154, 255);
    border: 0px;
}

QScrollBar:vertical {
            border: 0px solid #999999;
            background-color: rgb(34, 35, 52);
            width:14px;    
            margin: 0px 0px 0px 3px;
        }
        QScrollBar::handle:vertical {         
            min-height: 0px;
            border: 0px solid red;
            border-radius: 5px;
            background-color: rgb(92, 95, 141);
        }
        QScrollBar::add-line:vertical {       
            height: 0px;
            subcontrol-position: bottom;
            subcontrol-origin: margin;
        }
        QScrollBar::sub-line:vertical {
            height: 0 px;
            subcontrol-position: top;
            subcontrol-origin: margin;
        }

当我在 Qt 设计器中使用查看时,它工作正常

但是当我在 Designer 中预览滚动条时,它显示为默认滚动条。

我也尝试在 python 中运行代码并得到相同的结果。那么为什么 Designer 显示样式表可以正常工作,但实际上根本不起作用?

编辑: 问题已通过将滚动条样式表应用到滚动条的父元素来解决。

【问题讨论】:

  • 复杂小部件的某些样式和样式子类(最常见的是 QAbstractScrollArea 子类的滚动条)存在一些常见问题和不可靠的行为。你能提供 PyQt 和 OS 版本吗?同时,尝试直接在滚动条上设置 QScrollBar 相关的样式表。
  • @musicamante 我在错误的版本上使用了 PyQt5-tools,所以我确保我的 PyQt5 和 PyQt5-tools 版本匹配,然后再试一次。我得到了相同的结果,除了现在滚动条是showing a checkered pattern。我正在使用 PyQt5 5.15.2、PyQt5-tools 5.15.2.3.0.2、Python 3.8、Windows 10 64 位。
  • 您是否正在为任何父母设置其他样式表?您能否提供 ui 文件(可能只是一个可重现的最小示例)?
  • @musicamante 当然。 This is a copy of the file 与我使用的所有基本组件,只是剥离到只有桌子。编辑:我忘了提到我使用的样式表与原始帖子中的不同,但仍然遇到同样的问题。
  • 请编辑您的帖子并将代码嵌入其中,最好避免使用外部资源,因为它们可能存在或无法访问。

标签: python qt user-interface pyqt pyqt5


【解决方案1】:

tl;博士

确保您没有使用通用样式表;例如,在提供的 ui 文件中,将 TaskScreen 的样式表更改为:

QFrame#TaskScreen {
    background-color: rgb(34, 35, 52);
}

说明

在 Qt 小部件上设置样式表时,重要的是要注意两个方面:

  1. 与标准样式表一样,它们是级联的,这意味着子对象继承为其父对象设置的属性;
  2. 最好避免通用选择器或泛化属性;

第一点的问题在于,许多小部件实际上是复杂具有子小部件的小部件(有时即使在编程级别也无法访问,但仍会像 QWidgets 一样工作),最重要的是所有继承的类来自 QAbstractScrollArea(例如项目视图)总是有两个滚动条,并且由于这些滚动条是滚动区域的直接子级,它们将继承父样式表。

第二点的问题是,使用通用或通用选择器设置的属性可能会以意想不到的方式表现,具体取决于应用它们的小部件。

虽然对于没有子级的非常简单的小部件(QLabel、QPushButton)来说,使用这些样式表很好,但对于复杂的小部件,它可能会成为一个问题,尤其是当它们具有需要更全面样式的子控件时。

必须始终考虑stylesheet syntax 文档中的这一重要说明:

注意:对于 QComboBox 和 QScrollBar 等复杂的小部件,如果自定义了一个属性或子控件,所有其他属性或子控件必须自定义为嗯。

虽然您确实自定义了几乎所有属性,但您还为父小部件(UI 示例中的 TaskScreen QFrame)设置了通用属性:

background-color: rgb(34, 35, 52);

结果是它的所有子孙,无论他们是什么类,都将设置 priority 属性,并且考虑到上面的注释,结果是样式表不正确使用,因为 Qt 样式表样式解析器发现一个属性已设置但缺少其他重要的。

解决方案是为父级正确使用 type 选择器:

QFrame {
    background-color: rgb(34, 35, 52);
}

如果你想确保只有那个对象使用那个背景,你可以使用更多的specific selector,最常见的是对象名称选择器:

QFrame#TaskScreen {
    background-color: rgb(34, 35, 52);
}

或者,或者,类选择器,它只处理该类的实例,但它的子类:

.QFrame {
    background-color: rgb(34, 35, 52);
}

这很重要,因为实际上有很多类继承自 QFrame,包括 QLabel 和所有基于上述 QAbstractScrollAreas 的类。

除了上面解释的内容之外,根据经验,通常最好避免单独设置每个小部件的样式:您最终可能会在父级上设置通用样式表然后忘记它,然后经过大量修改后您可能会注意到意外像你这样的行为,找出问题所在真的很烦人。

通常更好的方法是设置“主”样式表(设置在顶层窗口、主窗口甚至 QApplication),正确使用选择器并仔细继承属性和状态,然后只更改您要更改其默认外观的特定小部件的小属性。

【讨论】:

  • 我真的很感谢关于样式表及其父母的解释!我不知道。但我尝试更改 TaskScreen 样式表以及向 MainFrame 添加“通用”样式表,但滚动条仍然存在同样的问题。
  • @NikosBeans 与您提供的 ui 一起工作,否则您要么没有正确设置选择器,要么在任何小部件父母。
  • 可能不是最好的解决方法,但我最终通过将滚动条样式表放在 TaskScreen 框架上解决了这个问题,并且修复了它。感谢所有帮助!
猜你喜欢
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-26
  • 1970-01-01
  • 2020-07-15
  • 2019-08-28
  • 1970-01-01
相关资源
最近更新 更多