【问题标题】:How to make the background color the same as the form background?如何使背景颜色与表单背景相同?
【发布时间】:2020-05-28 09:48:05
【问题描述】:

在 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 的正文更改为默认的表单背景颜色,但它不会更改选项卡的颜色!!

【问题讨论】:

    标签: python pyqt pyqt5 qtabwidget


    【解决方案1】:

    这个问题有两种可能的解决方案。

    这种行为的主要原因可以在正在使用的样式中找到。

    每种 Qt 样式都决定了如何使用调色板颜色来绘制小部件。这意味着即使您为(比方说)背景设置了特定颜色,保证小部件将具有该特定背景颜色。

    如果您考虑按钮,可以更好地解释这个概念:它们通常具有“阴影”渐变,即基于Button 颜色角色,但背景不是完全那种颜色。在下图中,我展示了一个按钮,我为 Button 角色设置了纯红色 (#ff0000) 颜色,但是,正如您所见,它不是红色:

    调色板颜色实际上是一种参考。

    一些小部件的绘画行为没有特定的角色,由样式决定使用哪个角色以及如何使用,QTabWidget就是这种情况。 在 Linux 上,默认样式通常是“Fusion”,它使用 Button 角色来绘制选项卡小部件的背景,但是当绘制该背景时,将使用基于该颜色的渐变 .同样,为Button 角色(又名标签小部件背景)应用了全红色,这不是真正的红色:

    对此有两种可能的解决方案。

    1。使用其他样式

    在处理 QTabWidget 时,“氧气”样式似乎与父背景更加一致。

    def main():
        app = QApplication([])
        app.setStyle(QStyleFactory.create('oxygen'))
    

    要知道系统上安装了哪些样式,只需致电QStyleFactory.keys()。请注意,并非所有样式都适用于每个系统。通常,“Fusion”和“Windows”都可用,这意味着如果您尝试访问“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))
    

    结果就是这样:

    【讨论】:

      【解决方案2】:

      我喜欢@musicamente 的回答。但值得指出的是,QTabWidget的背景颜色可以在QTabWidget的stylesheet属性中控制。

      根据docs,一个QTabWidget主要由一个QTabBar和一个QStackedWidget组成。您在样式表中使用 QTabBar 键来控制选项卡颜色,并使用 QStackedWidget 键来控制每个单独的页面。 Qt 窗口默认的浅灰色是#f0f0f0,所以你可以用它作为颜色。这是您可以输入到 Designer/Creator 的字符串(或者您可以使用 setStyleSheet('string') 以编程方式进行):

      QTabBar::tab {
          padding: 8px;
          background-color: #f0f0f0;
          border: 1px solid palette(mid);
          border-radius: 2px;
          margin: 0;
      }
      QTabBar::tab:selected {
          border-bottom: none;}
      QTabBar::tab:!selected {
          margin-top: 2px;
          margin-bottom: -2px;
          border-bottom: none;}
      QStackedWidget {
          background-color: #f0f0f0;
      }
      

      给了

      但是,我更喜欢选择的选项卡是不同的颜色,所以我只接受 QTabBar 的默认值。

      QStackedWidget {
          background-color: #f0f0f0;
      }
      

      给了

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-31
        • 2019-08-30
        • 1970-01-01
        • 2014-09-24
        • 1970-01-01
        • 2023-03-03
        相关资源
        最近更新 更多