在PyQt5中,我从QTabWidget中得到了一些意外的行为,背景似乎是白色的,而不是默认的表单颜色(大约是浅灰色)。这是一个例子:
# QTabWidget2.py
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QHBoxLayout, QVBoxLayout, QTabWidget, \
QGraphicsView, QFrame, QGridLayout
from PyQt5.QtGui import QPalette
from PyQt5.Qt import Qt
def main():
app = QApplication([])
mainForm = MainForm()
mainForm.show()
app.exec()
# end main
class MainForm(QWidget):
def __init__(self):
super().__init__()
# set default form size and location
self.setGeometry(300, 300, 800, 600)
# declare a graphics view
self.bigLabel = QLabel('Big Label')
self.setFontSize(self.bigLabel, 18)
self.bigLabel.setAlignment(Qt.AlignCenter)
self.bigLabel.setFrameStyle(QFrame.Panel)
# declare a small label and a button
self.label = QLabel('Label')
self.setFontSize(self.label, 12)
self.label.setAlignment(Qt.AlignCenter)
self.button = QPushButton('Button')
self.setFontSize(self.button, 12)
self.vboxLayout = QVBoxLayout()
self.vboxLayout.addWidget(self.label)
self.vboxLayout.addWidget(self.button)
self.vboxLayout.addStretch(1)
self.hboxLayout = QHBoxLayout()
self.hboxLayout.addWidget(self.bigLabel, 10)
self.hboxLayout.addLayout(self.vboxLayout, 1)
self.containerWidget = QWidget()
self.containerWidget.setLayout(self.hboxLayout)
self.tabWidget = QTabWidget()
self.tabWidget.addTab(self.containerWidget, 'My Tab')
self.gridLayout = QGridLayout()
self.gridLayout.addWidget(self.tabWidget)
self.setLayout(self.gridLayout)
# end function
def setFontSize(self, widget, fontSize):
font = widget.font()
font.setPointSize(fontSize)
widget.setFont(font)
# end function
# end class
if __name__ == '__main__':
main()
这是在Ubuntu 18.04上的外观:
我的问题是,如何使QTabWidget
背景的颜色与表单(在这种情况下为QWidget
)背景的颜色相同?
我尝试过的一些事情:
许多小部件具有这样的功能:
someWidget.setBackgroundBrush(self.palette().brush(QPalette.Window))
但是QTabWidget似乎没有setBackgroundBrush
或我可以找到的等效项。
我发现了一些建议使用样式表来实现此目的的帖子,但是我不确定如何设置。我是否需要对QTabWidget
进行子类化才能实现?另外,如何获得默认的背景表单颜色?我可以使用简单的猜测和检查来接近,但是在不同的平台上它可能会略有变化,因此并不是特别理想。
---编辑---
[Arrrrrrrggggggg !!!有时候Qt
真的很令人沮丧。如果我仅在声明QTabWidget
之后添加此内容:
widgetColor = self.palette().color(QPalette.Background)
widgetColorRgba = widgetColor.red(), widgetColor.green(), widgetColor.blue(), widgetColor.alpha()
print('widgetColorRgb = ' + str(widgetColorRgba))
styleSheetString = 'background-color: rgba(' + str(widgetColorRgba[0]) + ', ' + \
str(widgetColorRgba[1]) + ', ' + str(widgetColorRgba[2]) + ', ' + str(widgetColorRgba[3]) + ');'
print('styleSheetString = ' + str(styleSheetString))
# this line works
self.tabWidget.setStyleSheet(styleSheetString)
# this line does not work !!!
self.tabWidget.tabBar().setStyleSheet(styleSheetString)
它正确地将QTabWidget的主体更改为默认的表单背景颜色,但不会更改选项卡的颜色!
有两个可能的解决方案。
此行为的主要原因可以在所使用的style中找到。
每个Qt样式决定如何使用调色板颜色绘制小部件。这意味着,即使您为背景设置了特定的颜色(例如),也可以not保证小部件具有该特定的背景颜色。
如果您考虑按钮,则可以更好地解释此概念:按钮通常具有“阴影”渐变,该渐变基于Button
颜色角色,但背景并非[确切地该颜色。在下图中,我正在显示一个按钮,为该按钮设置Button角色的纯红色(#ff0000)颜色,但是,如您所见,它是not红色:
调色板颜色实际上是参考。
某些小部件的绘画行为没有特定的角色,这取决于样式来决定使用哪个角色以及如何使用,这就是QTabWidget的情况。在Linux上,默认样式通常是“融合”,它使用Button
角色绘制选项卡小部件的背景,但是在绘制背景时,将使用渐变
基于该颜色
。同样,为Button
角色应用了全红色(也就是标签窗口小部件背景),而不是实际的红色:有两种可能的解决方案。
1。使用其他样式
def main():
app = QApplication([])
app.setStyle(QStyleFactory.create('oxygen'))
2。使用全面的样式表
您的标签页不使用样式表设置的背景的原因是,由于样式(融合)仍使用上述应用于背景颜色的渐变,这是因为标签页可以使用不同的颜色,无论是是否选中(具体来说,如果选中,则比背景亮;如果未选中,则比背景暗)。为了避免这种情况,您需要为所有标签栏伪状态设置样式表。
bgd = 'rgba({}, {}, {}, {})'.format(*self.palette().color(QPalette.Window).getRgb()) # get the default margins for layouts and use them for text padding of # the tab; obviously, you can use your own default padding instead margins = [] for side in (QStyle.PM_LayoutTopMargin, QStyle.PM_LayoutRightMargin, QStyle.PM_LayoutBottomMargin, QStyle.PM_LayoutLeftMargin): margin = self.style().pixelMetric(side, None, None) if side in (QStyle.PM_LayoutTopMargin, QStyle.PM_LayoutBottomMargin): margin //= 2 margins.append('{}px'.format(margin)) padding = ' '.join(margins) self.tabWidget.setStyleSheet(''' /* this selector applies the background color only to QWidgets that are direct children of QTabWidget */ QTabWidget > QWidget {{ background-color: {bgd}; }} QTabBar::tab {{ padding: {padding}; border-left: 1px solid palette(mid); border-right: 1px solid palette(mid); border-top: 1px solid palette(mid); border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom: 1px solid palette(mid); margin: 0; }} QTabBar::tab:selected {{ border-color: palette(dark); border-bottom: none; }} QTabBar::tab:!selected {{ margin-top: 2px; margin-bottom: -2px; }} '''.format(bgd=bgd, padding=padding))
这就是结果: