我正在为“健全性”工具定制Qt小部件,运行检查后,包含QLabel的小部件的标题颜色将更改。我当前的问题是我希望标签颜色相对于背景颜色从黑色变为白色。
我还想做些类似融合样式的事情,如果我的标题仅填充一半,则文本将为黑白以与背景形成对比。 (对于QProgressBar真的很酷)
我目前已经尝试通过测试一些CSS实例来做到这一点,但我真的不知道CSS的工作原理,而且Qt样式表中的CSS似乎有所不同。
当然,我主要尝试通过样式表执行此操作,但是我想了解如何使用QPalette进行操作。
感谢您的帮助。
答案 0 :(得分:0)
如果直接在窗口小部件中绘制文本(例如在QProgressBar
中),则只需处理用于绘制背景的颜色。使用QPainter
和QPainter::setClipPath
方法很容易:
class ProgressBar(QLabel):
def __init__(self):
super().__init__()
self.progression = 0
self.startTimer(200)
def paintEvent(self, event):
text = "This is a text"
super().paintEvent(event)
painter = QPainter(self)
self.setFont(QFont("Helvetica", 24))
boundingRect = QRect(0, 0, self.width(), self.height())
progressionRect = boundingRect.adjusted(0, 0, - self.width() * (1 - self.progression), 0)
leftRect = boundingRect.adjusted(progressionRect.width(), 0, 0, 0)
painter.setBrush(Qt.black)
painter.drawRect(progressionRect)
painter.setClipRect(leftRect)
painter.drawText(boundingRect, Qt.AlignCenter,text)
painter.setPen(Qt.white)
painter.setClipRect(progressionRect)
painter.drawText(boundingRect, Qt.AlignCenter, text)
def timerEvent(self, event):
self.progression = min(1.0, self.progression + 0.02)
self.update()
if __name__ == "__main__":
app = QApplication(sys.argv)
p = ProgressBar()
p.resize(640, 480)
p.show()
sys.exit(app.exec_())
由于标签是标题中的另一个小部件,因此必须找到正确的颜色。如果标签知道其父级是您的标头(并且您在progress值中具有良好的访问器),则可以重用上面的解决方案。
如果您需要通过反转颜色来在小部件上绘制标签的通用方法,则可以在图像中绘制父级渲染,反转颜色并使用它来绘制文本。
一个简单的例子作为解释:
class Window(QLabel):
def __init__(self):
super().__init__()
self.progression = 0
self.startTimer(200)
def paintEvent(self, event):
super().paintEvent(event)
painter = QPainter(self)
boundingRect = QRect(0, 0, self.width(), self.height() * self.progression)
painter.setBrush(Qt.black)
painter.drawRect(boundingRect)
def timerEvent(self, event):
self.progression = min(1.0, self.progression + 0.02)
self.update()
class ContrastedText(QFrame):
def __init__(self, text="", parent=None):
super().__init__(parent)
self.text = text
def paintEvent(self, event):
super().paintEvent(event)
painter = QPainter(self)
self.setFont(QFont("Helvetica", 24))
boundingRect = QRect(0, 0, self.width(), self.height())
fm = QFontMetrics(painter.font())
textBoundingRect = fm.boundingRect(boundingRect, Qt.AlignCenter, self.text)
# No parent. The text is black
if not self.parent():
painter.drawText(boundingRect, Qt.AlignCenter, self.text)
return
# Get the parents render and invert its color to have the good constrast
render = QPixmap(self.parent().size()).toImage()
self.parent().render(render, QPoint(), QRegion(), QWidget.DrawWindowBackground)
render.invertPixels(QImage.InvertRgba)
# Define a clip path containing the text and draw the image
path = QPainterPath()
path.addText(textBoundingRect.topLeft(), painter.font(), self.text)
painter.setClipPath(path)
painter.drawImage(-self.mapTo(self.parent(), QPoint(0, 0)), render)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
layout = QVBoxLayout(window)
label = ContrastedText("This is a text")
layout.addWidget(label)
window.resize(640, 480)
window.show()
sys.exit(app.exec_())