2014-06-18 1 views
3

previous post의 대답으로 시작했지만 제대로 작동하지 않는 것 같습니다. 모든 행은 동일한 색상을 렌더링합니다. PySide에서 행의 배경 설정 QTreeWidget

나는

import sys 

from PySide import QtCore, QtGui 

class MainWindow(QtGui.QMainWindow): 
    def __init__(self, parent=None): 
     super(MainWindow, self).__init__(parent) 

     self.settingsTree = SettingsTree() 
     self.setCentralWidget(self.settingsTree) 

     self.locationDialog = None 

     # self.autoRefreshAct.setChecked(True) 
     # self.fallbacksAct.setChecked(True) 

     self.setWindowTitle("Test") 
     self.resize(500, 600) 
     self.setTreeDataObject(ItemManifest()) 
     self.settingsTree.setItemDelegate(SelectionColorDelegate(self.settingsTree)) 

    def setTreeDataObject(self, treeData): 
     self.settingsTree.setTreeDataObject(treeData) 

     # self.refreshAct.setEnabled(True) 
     # self.autoRefreshAct.setEnabled(True) 

ItemManifest이

class ItemManifest(QtCore.QObject): 
    def __init__(self, parent=None): 
     super(ItemManifest, self).__init__(parent) 
     self.myList = [{'name': 'a', 'vid':'1', 'pid': '1'}, 
         {'name': 'b', 'vid':'2', 'pid': '1'}, 
         {'name': 'c', 'vid':'3', 'pid': '1'}] 

이가 (이 일을 사물의 Qt는 방법 정말 확실하지 않은) 항목을 나열하려면 특정 데이터를 저장하는 데 사용되는 메인 윈도우 클래스를 생성 3 열이있는 실제 나무 위젯 :

class SettingsTree(QtGui.QTreeWidget): 
    def __init__(self, parent=None): 
     super(SettingsTree, self).__init__(parent) 

     self.setHeaderLabels(("Name", "vid", "pid")) 
     self.header().setResizeMode(0, QtGui.QHeaderView.Stretch) 
     self.header().setResizeMode(2, QtGui.QHeaderView.Stretch) 

     self.refreshTimer = QtCore.QTimer() 
     self.refreshTimer.setInterval(2000) 
     self.autoRefresh = False 

     self.groupIcon = QtGui.QIcon() 
     self.groupIcon.addPixmap(self.style().standardPixmap(QtGui.QStyle.SP_DirClosedIcon), 
       QtGui.QIcon.Normal, QtGui.QIcon.Off) 
     self.groupIcon.addPixmap(self.style().standardPixmap(QtGui.QStyle.SP_DirOpenIcon), 
       QtGui.QIcon.Normal, QtGui.QIcon.On) 
     self.keyIcon = QtGui.QIcon() 
     self.keyIcon.addPixmap(self.style().standardPixmap(QtGui.QStyle.SP_FileIcon)) 

     self.refreshTimer.timeout.connect(self.refresh) 

    def setTreeDataObject(self, treeData): 
     self.treeData = treeData 
     self.clear() 

     if self.treeData is not None: 
      self.treeData.setParent(self) 
      self.refresh() 
      if self.autoRefresh: 
       self.refreshTimer.start() 
     else: 
      self.refreshTimer.stop() 

    def sizeHint(self): 
     return QtCore.QSize(800, 600) 

    def setAutoRefresh(self, autoRefresh): 
     self.autoRefresh = autoRefresh 

     if self.treeData is not None: 
      if self.autoRefresh: 
       self.refresh() 
       self.refreshTimer.start() 
      else: 
       self.refreshTimer.stop() 

    def refresh(self): 
     if self.treeData is None: 
      return 

     # The signal might not be connected. 
     # try: 
     #  self.itemChanged.disconnect(self.updateSetting) 
     # except: 
     #  pass 

     self.updateChildItems(None) 

     # self.itemChanged.connect(self.updateSetting) 

    def event(self, event): 
     if event.type() == QtCore.QEvent.WindowActivate: 
      if self.isActiveWindow() and self.autoRefresh: 
       self.refresh() 

     return super(SettingsTree, self).event(event) 

    '''on change to settings update tree''' 
    def updateChildItems(self, parent): 
     dividerIndex = 0 

     for printer in self.treeData.myList: 
      childIndex = self.findChild(parent, printer['name'], 0) 
      if childIndex == -1 or childIndex >= dividerIndex: 
       if childIndex != -1: 
        child = self.childAt(parent, childIndex) 
        for i in range(child.childCount()): 
         self.deleteItem(child, i) 
        self.moveItemForward(parent, childIndex, dividerIndex) 
       else: 
        child = self.createItem(printer['name'], parent, dividerIndex) 
       child.setIcon(0, self.keyIcon) 
       dividerIndex += 1 
      else: 
       child = self.childAt(parent, childIndex) 

      child.setText(1, printer['vid']) 
      child.setText(2, printer['pid']) 

    def createItem(self, text, parent, index): 
     after = None 

     if index != 0: 
      after = self.childAt(parent, index - 1) 

     if parent is not None: 
      item = QtGui.QTreeWidgetItem(parent, after) 
     else: 
      item = QtGui.QTreeWidgetItem(self, after) 

     item.setText(0, text) 
     item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable) 
     return item 

    def deleteItem(self, parent, index): 
     if parent is not None: 
      item = parent.takeChild(index) 
     else: 
      item = self.takeTopLevelItem(index) 
     del item 

    def childAt(self, parent, index): 
     if parent is not None: 
      return parent.child(index) 
     else: 
      return self.topLevelItem(index) 

    def childCount(self, parent): 
     if parent is not None: 
      return parent.childCount() 
     else: 
      return self.topLevelItemCount() 

    def findChild(self, parent, text, startIndex): 
     for i in range(self.childCount(parent)): 
      if self.childAt(parent, i).text(0) == text: 
       return i 
     return -1 

    def moveItemForward(self, parent, oldIndex, newIndex): 
     for int in range(oldIndex - newIndex): 
      self.deleteItem(parent, newIndex) 

집합에 대한 색상 대표를 만듭니다. 팅 텍스트 행의 배경색 '는'녹색

class SelectionColorDelegate(QtGui.QStyledItemDelegate): 
    def __init__(self, parent): 
     super(SelectionColorDelegate, self).__init__(parent) 

    def initStyleOption(self, option, index): 
     # let the base class initStyleOption fill option with the default values 
     super(SelectionColorDelegate,self).initStyleOption(option, index) 
     # override what you need to change in option 
     if index.data() == 'a': 
      backColor = QtGui.QColor("green") 
      option.palette.setColor(QtGui.QPalette.Base, backColor) 
      option.backgroundBrush = backColor 

로 작동합니다

if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    mainWin = MainWindow() 
    mainWin.show() 
    sys.exit(app.exec_()) 

어느 배경색을 설정에서 내 시도가 작동 한 것으로 나타났습니다.

+0

[QTreeView의 행 배경색을 변경해도 작동하지 않습니다.] (http://stackoverflow.com/questions/14255224/changing-the-row-background-color-of-a-qtreeview-does-not-work)가 도움이 될 수 있습니다. 그것은 C++ 용이지만 Qt에서는 PySide/PyQt로 일대일로 이전 할 수 있습니다. 나는 당신과이 다른 코드를 테스트 할 시간이 없지만 upvoted 대답이있다. – Trilarion

답변

3

Qt를 더 배우고 나면 모델/뷰 관계를 사용하도록 코드를 리팩터링했습니다. 다음과 같이 모델은 데이터 방법을 QtCore.QAbstractItemModel에서 상속과 구현한다 : 나는 표준 트 리뷰 (또는 그 문제에 대해 다른 뷰)에 사용할 수 있었다

class MyTreeModel(QtCore.QAbstractItemModel): 

    def data(self, index, role): 
     if not index.isValid(): 
      return None 

     item = index.internalPointer() 

     if role == QtCore.Qt.BackgroundRole: 
      if item.status.status == 'Not installed': 
       return QtGui.QBrush(QtCore.Qt.lightGray) 
      if item.status.head_test_failed: 
       return QtGui.QBrush(QtCore.Qt.red) 
      if item.status.status == 'failure': 
       return QtGui.QBrush(QtCore.Qt.red) 
      if item.status.status == 'running': 
       return QtGui.QBrush(QtCore.Qt.green) 
      return QtGui.QBrush(QtCore.Qt.transparent) 

     if role != QtCore.Qt.DisplayRole: 
      return None 

     return item.data(index.column()) 

이 방법. role == QtCore.Qt.BackgroundRole은 모델에 서식 지정 요청임을 알립니다.