Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使背景颜色与窗体背景相同?_Python_Pyqt_Pyqt5_Qtabwidget - Fatal编程技术网

Python 如何使背景颜色与窗体背景相同?

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.

在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
来实现这一点?另外,如何获得默认的背景窗体颜色?我可以用简单的猜测和检查来接近,但是在不同的平台上可能会有轻微的变化,所以这不是特别需要的

---编辑---

啊,啊,啊,啊<代码>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))
这就是结果: