2015-08-15 43 views
0

我正在嘗試更改QTreeView中特定節點的圖標。節點將使用QCheckbox,並且基於應用程序邏輯,一些節點將改爲使用其他圖標進行節點選擇/未選擇狀態。setStyleSheet或QStyledItemDelegate QTreeView中的節點

下面的示例顯示瞭如何爲整個樹設置樣式表,但我不認爲可以爲樹中的單個節點設置樣式表。

#Based on http://stackoverflow.com/questions/5374168/unable-to-select-checkbox-inside-treeview 
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 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)) 

任何想法?

回答

1

A QCheckBox不使用圖標來顯示其狀態。您應該首先創建一個項目,通過任何方式,您可以獲得一個按照您的意願操作的小部件,並且具有正確的選中/未選中外觀。

一旦你有了,你會讓你的委託基於模型的數據項的某些屬性創建這樣的項目。例如,您可能有一個自定義角色,向您的委託表明應使用非默認控件類來編輯該項目。

+0

我不是100%清楚如何做到這一點,你知道以前做過這些事情的例子嗎? –

+1

@DonSmythe因爲缺乏更好的東西,你可以使用'QLabel'並在其上顯示正確的圖像。但理想情況下,請自行實施'QAbstractButton'。 –

相關問題