PySide 2 학습 기록 (22): QAbstractItemModel

Python 2.7 또는 Python 3.7 PySide 2 버 전: 5.11.2 공식 문서:http://doc.qt.io/qtforpython/index.html
qt 가 우리 가 필요 로 하 는 model 을 제공 하지 않 았 을 때, 자신 이 model 을 정의 하 는 것 을 고려 해 야 하기 때문에, QAbstractItemModel 과 같은 종 류 를 계승 하여 우리 자신의 model 을 실현 해 야 합 니 다.
공식 문서 에 따 르 면 QAbstractItemModel 클래스 를 계승 한 후 QAbstractItemModel 클래스 의 5 가지 방법 은 QAbstractItemModel. index (row, column [, parent = QModelIndex ()] QAbstractItemModel. parent (child) QAbstractItemModel. rowCount ([parent = QModelIndex ()]) QAbstractItemModel. columnCount ([parent = QModelIndex ()])QAbstractItemModel. data (index [, role = QT. DisplayRole]) 이 함수 들 은 모든 읽 기 전용 모델 에 사용 되 며 편집 가능 모델 의 가장 기본 적 인 부분 입 니 다.
먼저 첫 번 째 함수 index(row, column[, parent=QModelIndex()])) 를 보 려 면 두 개의 필수 매개 변 수 를 입력 해 야 합 니 다. 하 나 는 선택 가능 한 매개 변수 입 니 다. row 와 column 은 int 유형 으로 줄 과 열 을 표시 합 니 다. parent 는 이 노드 의 부모 가 누구 인지 표시 합 니 다 (트 리 구조 에서 부자 관계 와 관련 될 수 있 습 니 다). 유형 은 QModelIndex 입 니 다.반환 값 도 QModelIndex 형식 입 니 다.이 함 수 는 모델 에서 주어진 줄, 열, 부모 노드 의 항목 을 되 돌려 주 는 데 사 용 됩 니 다. 바로 모델 에서 특정한 항목 을 검색 하 는 것 입 니 다.parent(child) child 인 자 를 입력 합 니 다. 유형 은 QModelIndex 이 고 반환 유형 도 QModelIndex 입 니 다.함 수 는 모델 에서 주어진 항목 의 부모 항목 을 되 돌려 주 는 데 사 용 됩 니 다.rowCount([parent=QModelIndex()]) 선택 할 수 있 는 매개 변수 만 있 습 니 다. 부모 급 의 줄 수 를 되 돌려 줍 니 다. 유형 은 int 입 니 다. parent 에 들 어 오고 유효 할 때 부모 항목 의 하위 항목 수 를 되 돌려 줍 니 다.columnCount([parent=QModelIndex()]) 열 수 를 되 돌려 주 는 데 사용 할 선택 할 수 있 는 매개 변수 만 있 습 니 다.data(index[, role=Qt.DisplayRole]) 색인 index 를 입력 해 야 합 니 다. 형식 은 QModelIndex 이 고 옵션 role 은 기본적으로 Qt. DisplayRole 은 int 형식 입 니 다.이 함수 반환 값 형식 은 object 입 니 다.이 role 은 데이터 가 어떤 역할 로 나타 나 는 지 를 나타 낸다.DisplayRole 은 텍스트 표시 (편집 불가) 에 사 용 됩 니 다. DecorationRole 은 아이콘 형식 으로 사 용 됩 니 다. EditRole 은 편집기 의 편집 모드 표시 (편집 가능) 에 사 용 됩 니 다. 문 서 를 조회 하 십시오. 찾기 가 쉽 지 않 기 때문에 링크 를 놓 겠 습 니 다. ItemDataRole
다음은 실례 를 보 겠 습 니 다. 전편 에서 제 이 슨 모델 의 사용자 정의 모델 을 실현 하 는 데 사 용 된 모델 입 니 다.코드 원본 주소 (조금 바 꿨 습 니 다):https://github.com/dridk/QJsonModel/blob/master/qjsonmodel.py
#     model     item 
class QJsonTreeItem(object):
    def __init__(self, parent=None):
#   json       ,          
        self._parent = parent
        self._key = ""
        self._value = ""
        self._type = None
        self._children = list()

#       
    def appendChild(self, item):
        self._children.append(item)

#       
    def child(self, row):
        return self._children[row]

#       
    def parent(self):
        return self._parent

#         
    def childCount(self):
        return len(self._children)

#     
    def row(self):
        return (
            self._parent._children.index(self)
            if self._parent else 0
        )

#      
    @property
    def key(self):
        return self._key

#      
    @key.setter
    def key(self, key):
        self._key = key

#    
    @property
    def value(self):
        return self._value

#    
    @value.setter
    def value(self, value):
        self._value = value

#       
    @property
    def type(self):
        return self._type

#       
    @type.setter
    def type(self, typ):
        self._type = typ

#     ,value dict list  
    @classmethod
    def load(self, value, parent=None, sort=True):
        rootItem = QJsonTreeItem(parent)
        rootItem.key = "root"

        if isinstance(value, dict):
            items = (
                sorted(value.items())
                if sort else value.items()
            )

            for key, value in items:
                child = self.load(value, rootItem)
                child.key = key
                child.type = type(value)
                rootItem.appendChild(child)

        elif isinstance(value, list):
            for index, value in enumerate(value):
                child = self.load(value, rootItem)
                child.key = str(index)
                child.type = type(value)
                rootItem.appendChild(child)

        else:
            rootItem.value = value
            rootItem.type = type(value)

        return rootItem

#     json  ,   QAbstractItemModel 
class QJsonModel(QtCore.QAbstractItemModel):
    def __init__(self, parent=None):
        super(QJsonModel, self).__init__(parent)
#      
        self._rootItem = QJsonTreeItem()
        self._headers = ("key", "value")

#    load  ,     model 
    def load(self, document):
        """Load from dictionary
        Arguments:
            document (dict): JSON-compatible dictionary
        """

        assert isinstance(document, (dict, list, tuple)), (
            "`document` must be of dict, list or tuple, "
            "not %s" % type(document)
        )
#       model,   model         ,   model       
        self.beginResetModel()

        self._rootItem = QJsonTreeItem.load(document)
        self._rootItem.type = type(document)
#       
        self.endResetModel()

        return True

#   json  ,     dict
    def json(self, root=None):
        """Serialise model as JSON-compliant dictionary
        Arguments:
            root (QJsonTreeItem, optional): Serialise from here
                defaults to the the top-level item
        Returns:
            model as dict
        """

        root = root or self._rootItem
# genJson()       
        return self.genJson(root)

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

# internalPointer() QModelIndex      ,                  ,    QJsonTreeItem     
        item = index.internalPointer()

        if role == QtCore.Qt.DisplayRole:
            if index.column() == 0:
                return item.key

            if index.column() == 1:
                return item.value

        elif role == QtCore.Qt.EditRole:
            if index.column() == 1:
                return item.value

#     
    def setData(self, index, value, role):
        if role == QtCore.Qt.EditRole:
            if index.column() == 1:
                item = index.internalPointer()
                item.value = str(value)

                self.dataChanged.emit(index, index, [QtCore.Qt.EditRole])

                return True

        return False

#         
    def headerData(self, section, orientation, role):
        if role != QtCore.Qt.DisplayRole:
            return None

        if orientation == QtCore.Qt.Horizontal:
            return self._headers[section]

#          
    def index(self, row, column, parent=QtCore.QModelIndex()):
        if not self.hasIndex(row, column, parent):
            return QtCore.QModelIndex()

        if not parent.isValid():
            parentItem = self._rootItem
        else:
            parentItem = parent.internalPointer()

        childItem = parentItem.child(row)
        if childItem:
            return self.createIndex(row, column, childItem)
        else:
            return QtCore.QModelIndex()

#         
    def parent(self, index):
        if not index.isValid():
            return QtCore.QModelIndex()

        childItem = index.internalPointer()
        parentItem = childItem.parent()

        if parentItem == self._rootItem:
            return QtCore.QModelIndex()

        return self.createIndex(parentItem.row(), 0, parentItem)

#     ,     
    def rowCount(self, parent=QtCore.QModelIndex()):
        if parent.column() > 0:
            return 0

        if not parent.isValid():
            parentItem = self._rootItem
        else:
            parentItem = parent.internalPointer()

        return parentItem.childCount()

#     2 ,      2
    def columnCount(self, parent=QtCore.QModelIndex()):
        return 2

    def flags(self, index):
        flags = super(QJsonModel, self).flags(index)

        if index.column() == 1:
            return QtCore.Qt.ItemIsEditable | flags
        else:
            return flags

    def genJson(self, item):
        nchild = item.childCount()

        if item.type is dict:
            document = {}
            for i in range(nchild):
                ch = item.child(i)
                document[ch.key] = self.genJson(ch)
            return document

        elif item.type == list:
            document = []
            for i in range(nchild):
                ch = item.child(i)
                document.append(self.genJson(ch))
            return document

        else:
            return item.value

@ property, @ key. setter, @ classmethod 에서 알 아 볼 수 없 는 것 은 python 지식 을 보충 해 야 합 니 다.더 자세 한 사항 은 참고 하 시기 바 랍 니 다: QAbstractItemModel

좋은 웹페이지 즐겨찾기