pyqt5 Qradiobutton,QCheckBox颜色

发布于 2025-02-09 04:39:54 字数 705 浏览 1 评论 0原文

我使用的是无线电按钮和复选框,我想知道是否有一种方法可以更改复选标记/无线电指示周围的边框颜色。原因是因为当我在布局上切换到黑暗模式时,边框不再可见。

通过进入黑暗模式,我只是前景和背景颜色倒数。

class ChannelWindow(QWidget):
    """channel real-time display class (used for both default and custom types)"""
    def __init__(self, channel, this_type, comPort, spot):
        super().__init__()
        self.setGeometry(myWin.pos().x() - 535 + spot, myWin.pos().y() + 31, 520, 775)
        self.setWindowTitle(f"{channel} Data Window")
        self.setWindowIcon(QtGui.QIcon('files/images/ham.ico'))
        self.setStyleSheet(f"color: {foreground}; background-color: {background}")

“在此处输入图像说明”

I'm using radio buttons and checkboxes and I was wondering if there was a way to change the color of the border around the checkmark/radio indications. The reason is because when I switch to dark mode on my layout, the border is no longer visible.

By going to dark mode, I just inverse the foreground and background colors.

class ChannelWindow(QWidget):
    """channel real-time display class (used for both default and custom types)"""
    def __init__(self, channel, this_type, comPort, spot):
        super().__init__()
        self.setGeometry(myWin.pos().x() - 535 + spot, myWin.pos().y() + 31, 520, 775)
        self.setWindowTitle(f"{channel} Data Window")
        self.setWindowIcon(QtGui.QIcon('files/images/ham.ico'))
        self.setStyleSheet(f"color: {foreground}; background-color: {background}")

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黎夕旧梦 2025-02-16 04:39:54

除非您真的很彻底,否则仅设置基本样式表是不够的。大多数情况下,其结果是不一致的。

原因有两个:

  1. Qt使用 qStyle /em>小部件,计算其大小,定位子元素(例如QCheckbox的指示器)并正确绘制它们;
  2. QSS(QT样式表)是传播(因为它们遵循CSS的cascading 功能),并且需要特定的选择器来进行复杂小部件的子控制;设置样式表使QT使用内部QStyle(QStyleSheetStyle),有时完全覆盖了基本样式的默认行为;

最重要的是,复杂的小部件通常需要编写其内容的完整规格,尤其是对于子控制。而且,对于此类小部件,总是不鼓励使用通用属性(包括为父母这样做)。

从使用自定义的黑暗“主题”开始(请参阅这篇文章和相关答案)。这有一些警告:它实际上是 new 样式,因此您可能不喜欢它,或者想使用可以创建一些兼容性问题的自定义样式表。

但是,自定义样式表解决方案非常复杂,因为您应该指定所有子控件颜色,因为即使使用类选择器,也不足够。例如,QCheckBox要求您指定:: Indicator的属性随之而来的在QCheckBox的情况下,这意味着您必须为所有状态(禁用,检查,未检查等)编写规则,并为复选标记符号提供图像。

其他复杂的小部件(例如滚动条)需要仔细书面样式表,否则它们看起来会很糟糕。

您还应该认为某些颜色可能与所选的颜色不兼容(例如选择颜色)。

更简单的(通常更合规)解决方案是使用颜色构造函数设置 application 如果需要,要覆盖一些特定于小部件的颜色。

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

Palettes = []

class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self.setStyleSheet('''
            QGroupBox::title {
                color: red;
            }
        ''')

        layout = QVBoxLayout(self)
        darkCheck = QCheckBox('Switch dark mode')
        layout.addWidget(darkCheck)

        # just some random widgets
        group = QGroupBox('Hello!')
        layout.addWidget(group)
        groupLayout = QVBoxLayout(group)
        groupLayout.addWidget(QTextEdit('lorem ipsum ' * 1000))
        combo = QComboBox()
        combo.addItems(('a', 'b', 'c'))
        groupLayout.addWidget(combo)
        groupLayout.addWidget(QLineEdit('line edit'))

        darkCheck.clicked.connect(setDarkMode)


def setDarkMode(dark):
    app = QApplication.instance()
    if not Palettes:
        Palettes.append(app.palette())
        Palettes.append(QPalette(Qt.darkGray))
    app.setPalette(Palettes[dark])
    for window in QApplication.topLevelWidgets():
        old = window.styleSheet()
        if not old:
            window.setStyleSheet(' ')
        window.setStyleSheet(old)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    test = Widget()
    test.show()
    sys.exit(app.exec())

如您所见,我更改了Group Box标题的外观,但是我专门为其类的子控制器使用了选择器。

最后一部分是确保所有顶级小部件(及其子女)再次计算其样式表,即使他们没有。

Setting a basic stylesheet alone is insufficient, unless you are really thorough. Most of the times, its results are inconsistent.

There are two reasons for that:

  1. Qt uses QStyle to draw widgets, compute their sizes, position child elements (like the indicator of a QCheckBox) and properly draw them;
  2. QSS (Qt Style Sheets) are propagating (since they follow the cascading feature of CSS) and require specific selectors for sub-controls of complex widgets; setting style sheet makes Qt use an internal QStyle (QStyleSheetStyle) that sometimes completely overrides the default behavior of the basic style;

Most importantly, complex widgets usually require to write the full specifications of their contents, especially for sub-controls; and using generic properties is always discouraged for such widgets (including doing it for their parents).

There are various solutions to this, starting by using customized dark "themes" (see this post and the related answers). This has some caveats: it's actually a new style, so you might not like it, or would want to use custom style sheets that would create some compatibility issues.

The custom stylesheet solution, though, is quite more complex, as you should specify all sub controls colors, because even if you use class selectors, that won't be enough. For instance, QCheckBox requires that you specify the properties of ::indicator but, as explained above, once you set a property for a sub control, you must set all other properties along with it; in the case of QCheckBox this means that you have to write rules for all states (disabled, checked, unchecked, etc) and provide an image for the check mark symbol.

Other complex widgets (like scroll bars) require carefully written style sheets, otherwise they would look terrible.

You should also consider that some colors might not be compatible with the chosen ones (like the selection color).

A simpler (and, usually, more compliant) solution, is to set the application palette using the color constructor and eventually use carefully written style sheets to override some widget-specific colors if needed.

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

Palettes = []

class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self.setStyleSheet('''
            QGroupBox::title {
                color: red;
            }
        ''')

        layout = QVBoxLayout(self)
        darkCheck = QCheckBox('Switch dark mode')
        layout.addWidget(darkCheck)

        # just some random widgets
        group = QGroupBox('Hello!')
        layout.addWidget(group)
        groupLayout = QVBoxLayout(group)
        groupLayout.addWidget(QTextEdit('lorem ipsum ' * 1000))
        combo = QComboBox()
        combo.addItems(('a', 'b', 'c'))
        groupLayout.addWidget(combo)
        groupLayout.addWidget(QLineEdit('line edit'))

        darkCheck.clicked.connect(setDarkMode)


def setDarkMode(dark):
    app = QApplication.instance()
    if not Palettes:
        Palettes.append(app.palette())
        Palettes.append(QPalette(Qt.darkGray))
    app.setPalette(Palettes[dark])
    for window in QApplication.topLevelWidgets():
        old = window.styleSheet()
        if not old:
            window.setStyleSheet(' ')
        window.setStyleSheet(old)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    test = Widget()
    test.show()
    sys.exit(app.exec())

As you can see, I altered the appearance of the group box title, but I specifically used a selector for the subcontrol of its class.

The last part is to ensure that all the top level widgets (and their children) compute again their stylesheets, even if they do not have any.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文