更改 PyQt5 的调色板

Posted

技术标签:

【中文标题】更改 PyQt5 的调色板【英文标题】:Change palette of PyQt5 【发布时间】:2020-02-21 18:25:22 【问题描述】:

我正在尝试将 GUI 调色板从深色更改为浅色。

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


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 300)
        self.gridLayout = QGridLayout(Form)
        self.gridLayout.setObjectName("gridLayout")
        self.pushButton = QPushButton(Form)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
        self.pushButton_2 = QPushButton(Form)
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayout.addWidget(self.pushButton_2, 0, 1, 1, 1)

        self.retranslateUi(Form)
        QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.pushButton.setText(_translate("Form", "Dark"))
        self.pushButton_2.setText(_translate("Form", "Light"))
        self.pushButton.clicked.connect(self.changeSkinDark)
        self.pushButton_2.clicked.connect(self.changeSkinLight)

    def changeSkinDark(self):

        darkpalette = QPalette()
        darkpalette.setColor(QPalette.Window, QColor(41,44,51))
        darkpalette.setColor(QPalette.WindowText, Qt.white)
        darkpalette.setColor(QPalette.Base, QColor(15,15,15))
        darkpalette.setColor(QPalette.AlternateBase, QColor(41,44,51))
        darkpalette.setColor(QPalette.ToolTipBase, Qt.white)
        darkpalette.setColor(QPalette.ToolTipText, Qt.white)
        darkpalette.setColor(QPalette.Text, Qt.white)
        darkpalette.setColor(QPalette.Button, QColor(41,44,51))
        darkpalette.setColor(QPalette.ButtonText, Qt.white)
        darkpalette.setColor(QPalette.BrightText, Qt.red)
        darkpalette.setColor(QPalette.Highlight, QColor(100,100,225))
        darkpalette.setColor(QPalette.HighlightedText, Qt.black)
        app.setPalette(darkpalette)

    def changeSkinLight(self):

        palette = QGuiApplication.palette()
        app.setPalette(palette)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    app.setStyle('Fusion')
    Form = QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

这就是 PyQt5 所说的调色板可以设置为默认值的方式(changeSkinLight 方法)。

但是当我将功能分配给一个动作时。它只是运行 changeDarkSkin 而对 changeLightSkin 不做任何事情。如何像在 QtDesigner 中一样将调色板设置为默认值?

【问题讨论】:

我不懂你,你自己解释清楚,除了提供一个minimal reproducible example你想把调色板恢复到默认值吗? @eyllanesc 是的,我想恢复默认值。但我认为我阅读的内容已被弃用。任何提示/指针都非常受欢迎。已更新代码,使其可以运行。抱歉,代码很大,我用的是pyuic5。 @eyllanesc 刚刚更新了正确的代码 您可以将两个 app.setPalette() 调用更改为 Form.setPalette() 【参考方案1】:

如果要恢复应用程序调色板,则必须默认保存 QPalette:

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 300)
        self.gridLayout = QtWidgets.QGridLayout(Form)
        self.gridLayout.setObjectName("gridLayout")
        self.pushButton = QtWidgets.QPushButton(Form)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
        self.pushButton_2 = QtWidgets.QPushButton(Form)
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayout.addWidget(self.pushButton_2, 0, 1, 1, 1)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.pushButton.setText(_translate("Form", "Dark"))
        self.pushButton_2.setText(_translate("Form", "Light"))


class Form(QtWidgets.QWidget, Ui_Form):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.changeSkinDark)
        self.pushButton_2.clicked.connect(self.changeSkinLight)
        self.default_palette = QtGui.QGuiApplication.palette()

    @QtCore.pyqtSlot()
    def changeSkinDark(self):
        darkpalette = QtGui.QPalette()
        darkpalette.setColor(QtGui.QPalette.Window, QtGui.QColor(41, 44, 51))
        darkpalette.setColor(QtGui.QPalette.WindowText, QtCore.Qt.white)
        darkpalette.setColor(QtGui.QPalette.Base, QtGui.QColor(15, 15, 15))
        darkpalette.setColor(QtGui.QPalette.AlternateBase, QtGui.QColor(41, 44, 51))
        darkpalette.setColor(QtGui.QPalette.ToolTipBase, QtCore.Qt.white)
        darkpalette.setColor(QtGui.QPalette.ToolTipText, QtCore.Qt.white)
        darkpalette.setColor(QtGui.QPalette.Text, QtCore.Qt.white)
        darkpalette.setColor(QtGui.QPalette.Button, QtGui.QColor(41, 44, 51))
        darkpalette.setColor(QtGui.QPalette.ButtonText, QtCore.Qt.white)
        darkpalette.setColor(QtGui.QPalette.BrightText, QtCore.Qt.red)
        darkpalette.setColor(QtGui.QPalette.Highlight, QtGui.QColor(100, 100, 225))
        darkpalette.setColor(QtGui.QPalette.HighlightedText, QtCore.Qt.black)
        QtGui.QGuiApplication.setPalette(darkpalette)

    @QtCore.pyqtSlot()
    def changeSkinLight(self):
        QtGui.QGuiApplication.setPalette(self.default_palette)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Form()
    w.show()
    sys.exit(app.exec_())

注意:

某些版本的 PyQt5 和 python 似乎存在错误,因此解决方法是将调色板设置为窗口(感谢 @S.Nick):

@QtCore.pyqtSlot()
def changeSkinDark(self):
    # ...
    self.setPalette(darkpalette)

@QtCore.pyqtSlot()
def changeSkinLight(self):
    self.setPalette(self.default_palette)

【讨论】:

@In-Vader 你确定吗?您是否在未修改的情况下测试了我的代码?我刚刚对其进行了测试,它可以正常工作。你的操作系统,python版本,pyqt5版本是什么? 是的,我在 python 3.7.5、pyqt5、windows 10 上。它显示栏,但没有改变任何东西。抱歉打扰了 @In-Vader 你使用什么版本的 PyQt5?我已经在 Linux 上使用 Python 3.8.1 和 PyQt5 5.14.1 对其进行了测试,它可以正常工作。 @In-Vader 将 QtGui.QGuiApplication.setPalette(darkpalette) 更改为 self.setPalette(darkpalette)QtGui.QGuiApplication.setPalette(self.default_palette) 更改为 self.setPalette(self.default_palette) @S.Nick 成功了!谢谢你们俩。另外,我运行了 eyllanesc 发布的代码,它适用于 linux vm 上的 python 3.8.1,但不适用于 3.7.5,这很奇怪 tbh

以上是关于更改 PyQt5 的调色板的主要内容,如果未能解决你的问题,请参考以下文章

在 PyQt5 中获取 GUI 的标准调色板

为自定义 QWidget 设置背景颜色

使用角度材质和$ mdThemingProvider更改调色板颜色

Imagemagick convert -fill不会更改特定调色板区域的边缘

在 ImageSharp 中使用调色板/索引图像

当某些文件更改时,自动请求更改 Github 上的 PR