【问题标题】:PyQt4: How to color each tab in QTabWidget separately?PyQt4:如何分别为 QTabWidget 中的每个选项卡着色?
【发布时间】:2018-05-30 09:29:47
【问题描述】:

我正在开发一个带有 GUI 的项目,为此我使用 Python 和 PyQt4 模块。

这是我的演示代码:

import sys
from PyQt4 import QtGui, QtCore

class Window(QtGui.QMainWindow):

    def __init__(self):
        super(Window, self).__init__()
        self.setWindowTitle('PyQt4 demo')
        self.setGeometry(50, 50, 1000, 1000)
        self.createTabs()
        self.styleTabs()
        self.show()

    def createTabs(self):
        '''Creates a QTabWidget with 5 tabs,
        named 1, 2, 3, 4, 5
        '''

        self.tabs = QtGui.QTabWidget(self)
        self.tabs.resize(1000, 1000)

        contents1 = QtGui.QWidget()
        contents2 = QtGui.QWidget()
        contents3 = QtGui.QWidget()
        contents4 = QtGui.QWidget()
        contents5 = QtGui.QWidget()

        self.tabs.addTab(contents1, '1')
        self.tabs.addTab(contents2, '2')
        self.tabs.addTab(contents3, '3')
        self.tabs.addTab(contents4, '4')
        self.tabs.addTab(contents5, '5')

    def styleTabs(self):
        #Would like to add some code here which colors
        #each tab with a different color.
        pass


def run():
    app = QtGui.QApplication(sys.argv)
    GUI = Window()
    sys.exit(app.exec_())

run()

大多数对象(包括 QtabWidget 和 QTabBar)都支持使用 .setStyleSheet(str) 方法使用 CSS 进行样式设置。但是有了这个,我只能用相同的颜色为所有标签着色。我还找到了一种方法来为选定的、第一个、最后一个选项卡着色,但永远无法为例如一个选项卡着色:索引为 2。

例如:

self.tabs.setStyleSheet('''
    QTabBar::tab {background-color: green;}
    QTabBar::tab:selected {background-color: red;}
    QTabBar::tab:first {background-color: red;}
    QTabBar::tab:last {background-color: red;}
    ''')

我也尝试将颜色应用于当前的 QTabBar。这适用于 Qt,但显然不适用于 PyQt:

tab = self.tabs.tabBar()
tab.setStyleSheet('background-color: grey;')

PyQt4 着色方法也不起作用:

plt = QtGui.QPalette()
clr = QtGui.QColor()
clr.setRgb(100, 100, 100)
plt.setColor(10, clr)
tab.setPalette(plt)

我在网上搜索了很多,但没有找到任何解决此问题的方法。在这一点上,我什至不确定是否存在简单的解决方案。

有没有办法修改 PyQt4 源代码,所以可以应用上述技术之一?

附加信息:

  • Python 3.4 版

  • PyQt 版本 4.12

【问题讨论】:

  • 你在哪个平台上?有一个easy solution for linux,但我认为在 windows 或 mac 上没有任何方法可以做到这一点,因为它们使用 pixmaps 来渲染背景。
  • @ekhumoro 我正在使用 Windows,忘记提及了。我会尝试使用 QPainter 做什么。还是谢谢你的回复。

标签: python python-3.x pyqt pyqt4 qtabwidget


【解决方案1】:

不幸的是,QTabBar 并没有公开它的所有属性,因为它的内容不是以正常方式布局的子小部件,而是使用私有方法在内部绘制的。

不过,有两种可能。

  1. 使用它的paintEvent 手动绘制标签栏。使用 QStyle draw* 方法,可以随心所欲地自定义它,同时保持与当前主题的一致性;这不是一件容易的事,但可以做到。

  2. 只自定义当前选中标签的背景:使用QTabBar的currentChanged信号,你可以在每次当前索引改变时轻松重置样式表

这是一个例子:

def createTabs(self):
    #[create your tabs, then...]
    self.tabColors = {
        0: 'green', 
        1: 'red', 
        2: 'yellow', 
        3: 'orange', 
        4: 'blue', 
        }
    self.tabs.tabBar().currentChanged.connect(self.styleTabs)

[...]

def styleTabs(self, index):
    self.tabs.setStyleSheet('''
        QTabBar::tab {{}}
        QTabBar::tab:selected {{background-color: {color};}}
        '''.format(color=self.tabColors[index]))

您可能希望在第一次显示小部件时通过调用 styleTabs(0)“初始化”它,因为仅在触发信号时应用颜色。

【讨论】:

  • 感谢您的回答!我认为 QPaintEvent 将适合我的自定义需求。
  • @ZedsZen。正如我已经指出的,QPainter 方法适用于 linux,但不适用于 windows 或 mac。
  • @ekhumoro:“基本的”paintEvent 实现不起作用,但我认为它可以通过使用 QStyle 原始控件绘图来实现。它可能看起来不像一个标准选项卡,但我没有深入了解它,因为我只使用了基本绘图(doc.qt.io/qt-5/qdrawutil-h.html):QStyle 的绘图可能会实现这一点,但它有点复杂,需要更深入了解如何实际绘制每个小部件。除此之外,可以绘制自己的控件版本,而无需关心系统图形的一致性。
  • @musicamante。不,你完全错了——在 windows/mac 上根本不可能使用 QStyle 来做到这一点。如果您不相信我,请阅读Qt FAQ(但请注意,QProxyStyle 仅在 PyQt5 中可用,在 PyQt4 中不可用)。我已经提供了solution using QStyle drawing - 但它只适用于 linux。我认为这样做的唯一方法是绕过当前样式并从头开始绘制所有内容。
  • @ekhumoro 正如我所写,“我认为”您可以尝试绘制一个非常“相似”的 QTabBar 小部件(不是“原生”小部件):我所说的是使用原语和控件,而不是 QStyleOptionTab - 抱歉,我不清楚。但是,正如您也指出的那样,在这一点上,从头开始编写 draw 会容易得多:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-17
  • 1970-01-01
  • 2014-04-30
  • 1970-01-01
  • 1970-01-01
  • 2017-10-02
  • 2019-08-12
相关资源
最近更新 更多