为自定义 QWidget 设置背景颜色
Set background colour for a custom QWidget
我正在尝试创建一个背景颜色可以更改的自定义 QWidget(来自 PyQt5)。但是,所有设置背景颜色的标准方法似乎都不适用于自定义 QWidget class
到目前为止,我已经尝试通过 QSS 样式表和设置调色板来更改颜色。这适用于常规 QWidget,但出于某种原因不适用于自定义小部件。
我在 C++ 文档 https://wiki.qt.io/How_to_Change_the_Background_Color_of_QWidget 中找到了需要 paintEvent() 函数的参考自定义 QWidgets,并且确实在 Python 中找到了对它的引用。但是,实现链接的 paintevent 失败,因为 QStyleOption 在 PyQt5 中似乎不存在。
下面显示了我创建的 QWidget class 的高级别(它还包含一堆标签)和我用于 Widget 的 QSS(样式已在父 widget 中设置但已尝试设置直接)
class AlarmWidget(QWidget):
def __init__(self, alarm, parent=None):
super(AlarmWidget, self).__init__(parent)
self.setFixedHeight(200)
self.setProperty("active", True)
self.setAutoFillBackground(True)
p = self.palette()
p.setColor(self.backgroundRole(), PyQt5.QtCore.Qt.red)
self.setPalette(p)
AlarmWidget {
background-color: red
}
总的来说,无论我做什么,它都不让我为自定义 QWidget 设置背景颜色,因此非常感谢帮助
所有方法都适用于我,但如果你想实现 paintEvent,那么 PyQt5 的翻译是:
class AlarmWidget(QtWidgets.QWidget):
# ...
def paintEvent(self, event):
opt = QtWidgets.QStyleOption()
opt.initFrom(self)
p = QtGui.QPainter(self)
self.style().drawPrimitive(QtWidgets.QStyle.PE_Widget, opt, p, self)
最简单的修复方法是:
class AlarmWidget(QWidget):
def __init__(self, alarm, parent=None):
...
self.setAttribute(QtCore.Qt.WA_StyledBackground, True)
self.setStyleSheet('background-color: red')
只要将样式表应用于自定义小部件 或其祖先小部件之一 ,就会发生此问题。引用 QWidget.setPalette 文档:
Warning: Do not use this function in conjunction with Qt Style Sheets.
When using style sheets, the palette of a widget can be customized
using the "color", "background-color", "selection-color",
"selection-background-color" and "alternate-background-color".
但是,这里没有提到的是,出于性能原因,自定义小部件默认禁用样式表支持。因此,为了让您的示例正常工作,您必须 (1) 通过样式表设置背景颜色,以及 (2) 使用 WA_StyledBackground 小部件属性显式启用样式表支持。
下面显示了一个证明这一点的最小示例:
import sys
from PyQt5 import QtCore, QtWidgets
class AlarmWidget(QtWidgets.QWidget):
def __init__(self, alarm, parent=None):
super(AlarmWidget, self).__init__(parent)
self.setFixedHeight(200)
# self.setAutoFillBackground(True)
# p = self.palette()
# p.setColor(self.backgroundRole(), QtCore.Qt.red)
# self.setPalette(p)
self.setAttribute(QtCore.Qt.WA_StyledBackground, True)
self.setStyleSheet('background-color: red')
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.setStyleSheet('background-color: green')
self.widget = AlarmWidget('')
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.widget)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setWindowTitle('BG Colour Test')
window.setGeometry(600, 100, 300, 200)
window.show()
sys.exit(app.exec_())
这应该显示一个 window,其中包含一个带有绿色边框的红色矩形,如下所示:
要进一步测试,请仅在 AlarmWidget
class 中设置调色板,但不要在 Window
class 中设置样式表。这应该显示一个没有绿色边框的红色矩形。最后,仅在 both classes 中设置样式表 - 但没有 setAttribute
行。这应该显示一个没有内部红色矩形的纯绿色矩形(即不再应用自定义小部件上的样式表)。
我正在尝试创建一个背景颜色可以更改的自定义 QWidget(来自 PyQt5)。但是,所有设置背景颜色的标准方法似乎都不适用于自定义 QWidget class
到目前为止,我已经尝试通过 QSS 样式表和设置调色板来更改颜色。这适用于常规 QWidget,但出于某种原因不适用于自定义小部件。
我在 C++ 文档 https://wiki.qt.io/How_to_Change_the_Background_Color_of_QWidget 中找到了需要 paintEvent() 函数的参考自定义 QWidgets,并且确实在 Python 中找到了对它的引用。但是,实现链接的 paintevent 失败,因为 QStyleOption 在 PyQt5 中似乎不存在。
下面显示了我创建的 QWidget class 的高级别(它还包含一堆标签)和我用于 Widget 的 QSS(样式已在父 widget 中设置但已尝试设置直接)
class AlarmWidget(QWidget):
def __init__(self, alarm, parent=None):
super(AlarmWidget, self).__init__(parent)
self.setFixedHeight(200)
self.setProperty("active", True)
self.setAutoFillBackground(True)
p = self.palette()
p.setColor(self.backgroundRole(), PyQt5.QtCore.Qt.red)
self.setPalette(p)
AlarmWidget {
background-color: red
}
总的来说,无论我做什么,它都不让我为自定义 QWidget 设置背景颜色,因此非常感谢帮助
所有方法都适用于我,但如果你想实现 paintEvent,那么 PyQt5 的翻译是:
class AlarmWidget(QtWidgets.QWidget):
# ...
def paintEvent(self, event):
opt = QtWidgets.QStyleOption()
opt.initFrom(self)
p = QtGui.QPainter(self)
self.style().drawPrimitive(QtWidgets.QStyle.PE_Widget, opt, p, self)
最简单的修复方法是:
class AlarmWidget(QWidget):
def __init__(self, alarm, parent=None):
...
self.setAttribute(QtCore.Qt.WA_StyledBackground, True)
self.setStyleSheet('background-color: red')
只要将样式表应用于自定义小部件 或其祖先小部件之一 ,就会发生此问题。引用 QWidget.setPalette 文档:
Warning: Do not use this function in conjunction with Qt Style Sheets. When using style sheets, the palette of a widget can be customized using the "color", "background-color", "selection-color", "selection-background-color" and "alternate-background-color".
但是,这里没有提到的是,出于性能原因,自定义小部件默认禁用样式表支持。因此,为了让您的示例正常工作,您必须 (1) 通过样式表设置背景颜色,以及 (2) 使用 WA_StyledBackground 小部件属性显式启用样式表支持。
下面显示了一个证明这一点的最小示例:
import sys
from PyQt5 import QtCore, QtWidgets
class AlarmWidget(QtWidgets.QWidget):
def __init__(self, alarm, parent=None):
super(AlarmWidget, self).__init__(parent)
self.setFixedHeight(200)
# self.setAutoFillBackground(True)
# p = self.palette()
# p.setColor(self.backgroundRole(), QtCore.Qt.red)
# self.setPalette(p)
self.setAttribute(QtCore.Qt.WA_StyledBackground, True)
self.setStyleSheet('background-color: red')
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.setStyleSheet('background-color: green')
self.widget = AlarmWidget('')
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.widget)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setWindowTitle('BG Colour Test')
window.setGeometry(600, 100, 300, 200)
window.show()
sys.exit(app.exec_())
这应该显示一个 window,其中包含一个带有绿色边框的红色矩形,如下所示:
要进一步测试,请仅在 AlarmWidget
class 中设置调色板,但不要在 Window
class 中设置样式表。这应该显示一个没有绿色边框的红色矩形。最后,仅在 both classes 中设置样式表 - 但没有 setAttribute
行。这应该显示一个没有内部红色矩形的纯绿色矩形(即不再应用自定义小部件上的样式表)。