Как разделить один StyleSheet между несколькими виджетами?

В приведенном ниже коде создается QTreeWidget с двумя QComboBoxes установленными как его элементы-виджеты. Был класс QSS, который был присвоен первому ComboBox.

Вопрос: Поскольку QTreeWidgetItem являющийся родителем для ComboBoxes, не имеет .setStyleSheet() я должен перебирать каждый элемент-виджет, чтобы назначать или изменять его стили. Излишне говорить, что это exra-computing замедляет время ответа графического интерфейса. Вместо этого было бы здорово, если бы все поле со списками элементов разделили один и тот же стиль. Поэтому изменение одного стиля таблицы ComboBox изменит внешний вид всего элемента Comboboxes сразу. Как его достичь?

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 ответа

Лично я не вижу проблемы с настройкой стилей по отдельности в отношении использования ЦП и может быть более явным. Тем не менее, следующие работы: вы устанавливаете стиль для родительского виджета, а дети наследуют эти стили, если не указано иное

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().


Вот как я это сделал, используя сигналы/слоты, чтобы изменить и повторно применить таблицу стилей к подклассифицированным виджетам. Мне нравится этот подход, так как нет необходимости перебирать все QListWidgetsItems и его ItemWidgets. ItemWidgets прослушивают Сигнал и сами обновляют свои стили. Я также реализовал здесь механизм выбора QTreeWidgetItem когда QTreeWidgetItem один из его Item-Widgets.

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_())

licensed under cc by-sa 3.0 with attribution.