QTreeView 中节点的 setStyleSheet 或 QStyledItemDelegate
setStyleSheet or QStyledItemDelegate for a node in QTreeView
我正在尝试更改 QTreeView 中特定节点的图标。节点将使用 QCheckbox,并且根据应用程序逻辑,一些节点将改为使用其他图标表示节点 selected/unselected 状态。
下面的示例显示了如何为整个树设置样式表,但我认为我不能为树中的单个节点设置样式表。
#Based on
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
changeStyleTriggered = QtCore.pyqtSignal()
def __init__(self):
QtGui.QWidget.__init__(self)
self.createTree()
self.connectSlots()
def createTree(self):
data = ['A', 'B', 'C', 'D', 'E', 'F']
model = MyTreeView(data)
self.treeView = QTreeView()
self.treeView.setModel(model)
layout = QtGui.QVBoxLayout()
layout.addWidget(self.treeView)
self.changeIconPushButton = QtGui.QPushButton("Change a single icon")
layout.addWidget(self.changeIconPushButton)
self.setLayout(layout)
def fireChangeStyleSignal(self):
self.changeStyleTriggered.emit()
@pyqtSlot()
def changeStyleSignal(self):
print(">>changeStyleSignal()")
self.setStyleSheet("QTreeView::indicator:unchecked {image: url(:/icons/image.png);}")
def connectSlots(self):
self.changeStyleTriggered.connect(self.changeStyleSignal)
self.changeIconPushButton.clicked.connect(self.fireChangeStyleSignal)
class TestItem():
def __init__(self, name, checked):
self.checked = checked
self.name = name
class MyTreeView(QAbstractListModel):
def __init__(self, args, parent=None):
super(StbTreeView, self).__init__(parent)
self.args = []
for item_name in args:
self.args.append(TestItem(item_name, False))
for item in self.args:
print (item.name)
def rowCount(self, parent):
return len(self.args)
def headerData(self, section, orientation, role):
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
return "Nodes"
def flags(self, index):
return Qt.ItemIsUserCheckable | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsEnabled
def data(self, index, role=Qt.DisplayRole):
if role == Qt.DisplayRole:
row = index.row()
print (self.args[row].name)
return self.args[row].name
if role == Qt.CheckStateRole:
row = index.row()
print (self.args[row].checked)
if self.args[row].checked == False:
return Qt.Unchecked
else:
return Qt.Checked
def setData(self, index, value, role):
if role == Qt.CheckStateRole:
row = index.row()
self.args[row].checked = not self.args[row].checked
return True
def main():
myapp = QApplication(sys.argv)
window = Window()
window.show()
myapp.exec_()
if __name__ == '__main__':
main()
另一种选择是使用 QStyledItemDelegate。下面是一个小的class来改变字体,但是我还没有弄清楚如何用delegate改变单个图标。
class BoldDelegate(QtGui.QStyledItemDelegate):
def paint(self, painter, option, index):
option.font.setWeight(QtGui.QFont.Bold)
QtGui.QStyledItemDelegate.paint(self, painter, option, index)
并使用它 运行 这个(例如在 QTreeView 的 @pyqtSlot() 中):
self.setItemDelegate(BoldDelegate(self))
有什么想法吗?
A QCheckBox
不使用图标来显示其状态。您应该首先创建一个项目,在该项目中,您可以通过任何方式获得一个按您希望的方式运行的小部件,具有正确的 checked/unchecked 外观。
完成后,您将让您的代表根据模型数据项的某些 属性 创建此类项。例如,您可能有一个自定义角色,它向您的委托人指示应该使用非默认小部件 class 来编辑项目。
我正在尝试更改 QTreeView 中特定节点的图标。节点将使用 QCheckbox,并且根据应用程序逻辑,一些节点将改为使用其他图标表示节点 selected/unselected 状态。
下面的示例显示了如何为整个树设置样式表,但我认为我不能为树中的单个节点设置样式表。
#Based on
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
changeStyleTriggered = QtCore.pyqtSignal()
def __init__(self):
QtGui.QWidget.__init__(self)
self.createTree()
self.connectSlots()
def createTree(self):
data = ['A', 'B', 'C', 'D', 'E', 'F']
model = MyTreeView(data)
self.treeView = QTreeView()
self.treeView.setModel(model)
layout = QtGui.QVBoxLayout()
layout.addWidget(self.treeView)
self.changeIconPushButton = QtGui.QPushButton("Change a single icon")
layout.addWidget(self.changeIconPushButton)
self.setLayout(layout)
def fireChangeStyleSignal(self):
self.changeStyleTriggered.emit()
@pyqtSlot()
def changeStyleSignal(self):
print(">>changeStyleSignal()")
self.setStyleSheet("QTreeView::indicator:unchecked {image: url(:/icons/image.png);}")
def connectSlots(self):
self.changeStyleTriggered.connect(self.changeStyleSignal)
self.changeIconPushButton.clicked.connect(self.fireChangeStyleSignal)
class TestItem():
def __init__(self, name, checked):
self.checked = checked
self.name = name
class MyTreeView(QAbstractListModel):
def __init__(self, args, parent=None):
super(StbTreeView, self).__init__(parent)
self.args = []
for item_name in args:
self.args.append(TestItem(item_name, False))
for item in self.args:
print (item.name)
def rowCount(self, parent):
return len(self.args)
def headerData(self, section, orientation, role):
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
return "Nodes"
def flags(self, index):
return Qt.ItemIsUserCheckable | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsEnabled
def data(self, index, role=Qt.DisplayRole):
if role == Qt.DisplayRole:
row = index.row()
print (self.args[row].name)
return self.args[row].name
if role == Qt.CheckStateRole:
row = index.row()
print (self.args[row].checked)
if self.args[row].checked == False:
return Qt.Unchecked
else:
return Qt.Checked
def setData(self, index, value, role):
if role == Qt.CheckStateRole:
row = index.row()
self.args[row].checked = not self.args[row].checked
return True
def main():
myapp = QApplication(sys.argv)
window = Window()
window.show()
myapp.exec_()
if __name__ == '__main__':
main()
另一种选择是使用 QStyledItemDelegate。下面是一个小的class来改变字体,但是我还没有弄清楚如何用delegate改变单个图标。
class BoldDelegate(QtGui.QStyledItemDelegate):
def paint(self, painter, option, index):
option.font.setWeight(QtGui.QFont.Bold)
QtGui.QStyledItemDelegate.paint(self, painter, option, index)
并使用它 运行 这个(例如在 QTreeView 的 @pyqtSlot() 中):
self.setItemDelegate(BoldDelegate(self))
有什么想法吗?
A QCheckBox
不使用图标来显示其状态。您应该首先创建一个项目,在该项目中,您可以通过任何方式获得一个按您希望的方式运行的小部件,具有正确的 checked/unchecked 外观。
完成后,您将让您的代表根据模型数据项的某些 属性 创建此类项。例如,您可能有一个自定义角色,它向您的委托人指示应该使用非默认小部件 class 来编辑项目。