Python 如何使背景颜色与窗体背景相同?
在PyQt5中,我从QTabWidget中获得了一些意想不到的行为,背景似乎是白色,而不是默认的表单颜色(大致为浅灰色)。以下是一个例子:Python 如何使背景颜色与窗体背景相同?,python,pyqt,pyqt5,qtabwidget,Python,Pyqt,Pyqt5,Qtabwidget,在PyQt5中,我从QTabWidget中获得了一些意想不到的行为,背景似乎是白色,而不是默认的表单颜色(大致为浅灰色)。以下是一个例子: # QTabWidget2.py from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QHBoxLayout, QVBoxLayout, QTabWidget, \ QGraphicsView, QFrame, QGridLayout from PyQt5.
# 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
来实现这一点?另外,如何获得默认的背景窗体颜色?我可以用简单的猜测和检查来接近,但是在不同的平台上可能会有轻微的变化,所以这不是特别需要的
---编辑---
啊,啊,啊,啊<代码>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的主体更改为默认表单背景颜色,但不会更改选项卡的颜色
这个问题有两种可能的解决方案 这种行为的主要原因可以在正在使用的样式中找到 每个Qt样式决定如何使用调色板颜色绘制小部件。这意味着,即使您为(比方说)背景设置了特定的颜色,也不能保证小部件将具有特定的背景颜色 如果您考虑按钮,这个概念会得到更好的解释:它们通常有一个“阴影”渐变,这是基于
按钮颜色角色,但背景并不完全是那种颜色。在下图中,我显示了一个按钮,我为按钮角色设置了纯红色(#ff0000)颜色,但正如您所看到的,它不是红色:
调色板颜色实际上是一种参考
有些小部件的绘制行为没有特定的角色,由样式决定使用哪个角色以及如何使用,QTabWidget就是这样。
在Linux上,默认样式通常是“Fusion”,它使用按钮
角色绘制选项卡小部件的背景,但在绘制背景时,将使用基于该颜色的渐变。同样,为按钮
角色(也称为选项卡小部件背景)应用的全红色,不是实际的红色:
有两种可能的解决方案
1.使用另一种风格
在处理QTabWidget时,“Oxygen”风格似乎更符合父背景
def main():
app = QApplication([])
app.setStyle(QStyleFactory.create('oxygen'))
要知道系统上安装了哪些样式,只需调用QStyleFactory.keys()
。请注意,并非所有样式都适用于每个系统。通常,“Fusion”和“Windows”都是可用的,这意味着如果您尝试访问“Oxygen”样式但未安装,则将使用回退样式
2.对选项卡栏也使用全面的样式表
选项卡不使用样式表设置的背景的原因是,样式(融合)仍在使用应用于背景颜色的上述渐变,这是因为无论是否选中,选项卡都可以有不同的颜色(特别是,如果选中,则比背景亮,如果未选中,则颜色更暗).
为了避免这种情况,需要为所有tabbar伪状态设置样式表
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))
这就是结果: