Как обновить данные QTreeView - PullRequest
0 голосов
/ 21 октября 2019

Как мне обновить данные (текст, значки) в Qtreeview, когда объект, на который он ссылается, изменился? Без сброса, какие элементы были свернуты, а какие были открыты.

В идеале это было бы легко достижимо при настройке модели, но я не совсем уверен, как это сделать в этом случае.

enter image description here

################################################################################
# Imports
################################################################################ 
import os, sys, re, pprint
from Qt import QtGui, QtWidgets, QtCore


################################################################################
# Base Class
################################################################################ 
class PlayerItem(object):
    def __init__(self, name, playerStatus, team, teamStatus):
        super(PlayerItem, self).__init__()
        self._playerName = ''
        self._teamName = ''
        self._playerStatus = 'injured'
        self._teamStatus = 0

        self.setPlayerName(name)
        self.setTeamName(team)
        self.setPlayerStatus(playerStatus)
        self.setTeamStatus(teamStatus)

    # Methods
    def setPlayerName(self, value):
        self._playerName = value

    def getPlayerName(self):
        return self._playerName

    def setTeamName(self, value):
        self._teamName = value

    def getTeamName(self):
        return self._teamName

    def setPlayerStatus(self, value):
        self._playerStatus = value

    def getPlayerStatus(self):
        return self._playerStatus

    def setTeamStatus(self, value):
        self._teamStatus = value

    def getTeamStatus(self):
        return self._teamStatus


################################################################################
# TreeView
################################################################################ 
class PlayerItemTreeView(QtWidgets.QTreeView):

    def __init__(self, parent=None):
        super(PlayerItemTreeView, self).__init__(parent)

        # properties
        self.resize(600,600)
        self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)

        self.itemModel = QtGui.QStandardItemModel()
        self.itemProxyModel = QtCore.QSortFilterProxyModel()
        self.itemProxyModel.setSourceModel(self.itemModel)
        self.setModel(self.itemProxyModel)

        self.populate({
                'Group A': [
                    PlayerItem('Kevin', 'injured', 'Packers', 0),
                    PlayerItem('Mitch', 'reserves', 'Cowboys', 0)
                ],
                'Group B': [
                    PlayerItem('Mike', 'active', 'Packers', 1),
                    PlayerItem('Heather', 'injured', 'Steelers', 1),
                    PlayerItem('Leslie', 'active', 'Steelers', 0),
                    PlayerItem('Kaite', 'reserves', 'Patriots', 1)
                ]
            })


    # Methods
    def getPlayerStatusPixmap(self, status):
        '''
        Description:
            Returns a list of statuses from shotgun with added dict field 'pixmap'
        '''
        px = QtGui.QPixmap(64,16)
        # px = QtGui.QImage(48,16, QtGui.QImage.Format_RGB16)
        px.fill(QtCore.Qt.transparent)

        color = {
            'active': QtGui.QColor(20,220,40),
            'reserves': QtGui.QColor(220,240,0),
            'injured': QtGui.QColor(240,40,40)
        }

        painter = QtGui.QPainter(px)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setBrush(color[status])
        painter.setPen(QtGui.QPen(QtCore.Qt.NoPen))
        painter.drawRoundedRect(px.rect(), 2, 2)

        fnt = painter.font()
        fnt.setPixelSize(11)
        painter.setFont(fnt)
        painter.setPen(QtGui.QPen(QtGui.QColor(0,0,0)))
        painter.drawText(px.rect(), QtCore.Qt.AlignCenter, '{}'.format(status))
        painter.end()    
        return px


    def getTeamStatusPixmap(self, status):
        '''
        Description:
            Returns a list of statuses from shotgun with added dict field 'pixmap'
        '''
        px = QtGui.QPixmap(16,16)
        px.fill(QtCore.Qt.transparent)

        painter = QtGui.QPainter(px)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setBrush(QtGui.QColor(0,0,180))
        painter.setPen(QtGui.QPen(QtCore.Qt.NoPen))
        painter.drawRoundedRect(px.rect(), 2, 2)

        fnt = painter.font()
        fnt.setPixelSize(11)
        painter.setFont(fnt)
        painter.setPen(QtGui.QPen(QtGui.QColor(240,240,240)))
        painter.drawText(px.rect(), QtCore.Qt.AlignCenter, '{}'.format(status))
        painter.end()    
        return px


    def resizeColumns(self):
        for i in range(self.itemModel.columnCount()):
            self.resizeColumnToContents(i)


    def populateChildren(self, items, parent):
        for x in items:
            col1 = QtGui.QStandardItem(x.getPlayerName())
            col1.setData(x, role=QtCore.Qt.UserRole)
            col1.setData(self.getPlayerStatusPixmap(x.getPlayerStatus()), role=QtCore.Qt.DecorationRole)

            col2 = QtGui.QStandardItem(x.getTeamName())
            col2.setData(x, role=QtCore.Qt.UserRole)
            col2.setData(self.getTeamStatusPixmap(x.getTeamStatus()), role=QtCore.Qt.DecorationRole)

            # Append Item
            parent.appendRow([col1, col2]) 


    def populate(self, data):
        sortColumn = self.header().sortIndicatorSection()
        sortDirection = self.header().sortIndicatorOrder()
        self.itemModel.clear()
        self.setSortingEnabled(False)
        self.itemModel.setHorizontalHeaderLabels(['Name', 'Team'])

        root = self.itemModel.invisibleRootItem()

        if not isinstance(data, dict):
            # Flat List
            self.populateChildren(data, root)
        else:
            for key, values in data.items():
                parent = QtGui.QStandardItem()
                parent.setData(key, role=QtCore.Qt.DisplayRole)
                parent.setData(QtGui.QColor(30,170,255), role=QtCore.Qt.ForegroundRole)
                fnt = parent.font()
                fnt.setBold(True)
                parent.setFont(fnt)
                root.appendRow([parent])
                self.populateChildren(values, parent)

        # Restore
        self.setSortingEnabled(True)
        self.sortByColumn(sortColumn, sortDirection)
        self.expandAll()
        self.resizeColumns()



def unitTest_PlayerItemTreeView():
    app = QtWidgets.QApplication(sys.argv)
    ex = PlayerItemTreeView()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    pass
    unitTest_PlayerItemTreeView()
...