如何在多个项目小部件之间共享单个StyleSheet?

时间:2014-08-11 22:09:03

标签: python pyqt

以下代码创建QTreeWidget,其中QComboBoxes设置为其项目窗口小部件。 有一个QSS样式表分配给第一个ComboBox。

问题:由于作为ComboBoxes父级的QTreeWidgetItem没有.setStyleSheet()方法,我必须遍历每个项目小部件以分配或修改其styleSheets。毋庸置疑,这种exra-computing减慢了GUI的响应时间。相反,如果所有Item的组合框共享相同的styleSheet,那将会很棒。因此,更改单个ComboBox的样式表将立即改变所有项目的组合框的外观。如何实现呢?

enter image description here

from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])

class Tree(QtGui.QTreeWidget):
    def __init__(self, *args, **kwargs):
        super(Tree, self).__init__()
        for each in ['Item_1','Item_2','Item_3','Item_4','Item_5']:
            item=QtGui.QTreeWidgetItem([each])
            self.addTopLevelItem(item)
            combo1=QtGui.QComboBox()
            combo2=QtGui.QComboBox()
            self.setItemWidget(item, 1, combo1)
            self.setItemWidget(item, 2, combo2)
            comboStyle="QComboBox {background-color: #7A7A7A; border: 1px solid black;}"
            combo1.setStyleSheet(comboStyle)
        self.setColumnCount(5)
        self.resize(360,240)
        self.show()

tree=Tree()
sys.exit(app.exec_())

2 个答案:

答案 0 :(得分:1)

就CPU使用情况而言,就个人而言,我没有看到单独设置样式的问题,而且可能更明确。但是,以下工作原理:您为父窗口小部件设置样式,除非另有指定,否则子项将继承这些样式

class Tree(QtGui.QTreeWidget):
    def __init__(self, *args, **kwargs):
        super(Tree, self).__init__()
        comboStyle="QComboBox {background-color: #7A7A7A; border: 1px solid black;}"
        self.setStyleSheet(comboStyle)
        for each in ['Item_1','Item_2','Item_3','Item_4','Item_5']:
            item=QtGui.QTreeWidgetItem([each])
            self.addTopLevelItem(item)
            combo1=QtGui.QComboBox()
            combo2=QtGui.QComboBox()
            self.setItemWidget(item, 1, combo1)
            self.setItemWidget(item, 2, combo2)
        self.setColumnCount(5)
        self.resize(360,240)
        self.show()

请注意,对我而言,这会导致更改列宽,因此您可能需要resizeColumnToContents()

答案 1 :(得分:0)

以下是我使用信号/插槽来更改和重新应用样式表到子类小部件的方法。我喜欢这种方法,因为不需要遍历所有QListWidgetsItems及其ItemWidgetsItemWidgets正在监听Signal并自行更新其样式。我还在这里实现了一种机制,可以在点击QTreeWidgetItem之一时选择Item-Widgets

enter image description here

from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])

class LineEdit(QtGui.QLineEdit):
    def __init__(self, tree, item):
        QtGui.QLineEdit.__init__(self)
        self.tree=tree
        self.item=item
        self.restyle()

    def mousePressEvent(self, event):
        self.emit(QtCore.SIGNAL('click!'),self)

    def restyle(self): 
        if self.item.isSelected(): bgColor='#7A7A7A'
        elif self.tree.indexFromItem(self.item).row()%2: bgColor='#1F1F1F'
        else: bgColor='#262626'

        stylesheet="QLineEdit {{background-color: {0}; border: 1px solid black;}}".format(bgColor) 
        self.setStyleSheet(stylesheet)
        for i in range(5): self.item.setBackgroundColor(i, QtGui.QColor(bgColor))

class ComboBox(QtGui.QComboBox):
    def __init__(self, tree, item):
        QtGui.QComboBox.__init__(self)
        self.tree=tree
        self.item=item
        self.restyle()

    def mousePressEvent(self, event): 
        self.emit(QtCore.SIGNAL('click!'),self)

    def restyle(self): 
        if self.item.isSelected(): bgColor='#7A7A7A'
        elif self.tree.indexFromItem(self.item).row()%2: bgColor='#1F1F1F'
        else: bgColor='#262626'

        stylesheet="QComboBox {{background-color: {0}; border: 1px solid black;}}".format(bgColor) 
        self.setStyleSheet(stylesheet)
        for i in range(5): self.item.setBackgroundColor(i, QtGui.QColor(bgColor))

class Tree(QtGui.QTreeWidget):
    def __init__(self, *args, **kwargs):
        super(Tree, self).__init__()
        self.setAutoFillBackground(True)
        self.setBackgroundRole(QtGui.QPalette.Base)
        p = self.palette()
        p.setColor(self.backgroundRole(), QtGui.QColor("#0F0F0F"))
        self.setPalette(p)        
        self.setColumnCount(5)
        for each in ['Item_1','Item_2','Item_3','Item_4','Item_5']:
            item=QtGui.QTreeWidgetItem([each])
            self.addTopLevelItem(item)
            combo=ComboBox(self, item)
            lineEdit=LineEdit(self, item)

            combo.connect(self, QtCore.SIGNAL('selectionChanged!'), combo.restyle)
            lineEdit.connect(self, QtCore.SIGNAL('selectionChanged!'), lineEdit.restyle)

            self.setItemWidget(item, 1, combo)
            self.setItemWidget(item, 2, lineEdit)

            self.connect(combo, QtCore.SIGNAL('click!'), self.select)
            self.connect(lineEdit, QtCore.SIGNAL('click!'), self.select)

        self.itemSelectionChanged.connect(self.emitOnChange)

        self.resize(480,120)
        self.show()

    def select(self, itemWidget):
        for i in range(self.topLevelItemCount()):
            self.topLevelItem(i).setSelected(False)

        itemWidget.item.setSelected(True)

    def emitOnChange(self, arg=None):
        self.emit(QtCore.SIGNAL('selectionChanged!'),self)

tree=Tree()
sys.exit(app.exec_())