QTreeView不显示项目

时间:2019-10-04 15:31:31

标签: python pyside

我创建了一个简单的QTreeView小部件,并且将QStandardItemModel子类化,但是由于某些原因,当尝试访问它的数据时,我的所有行都没有显示在视图中或打印。这似乎很简单。我必须忽略模型中使它根本无法工作的某些内容。列虽然显示正确。我将打印语句放在def data(...)中,但它们从未触发,为什么?

enter image description here

import os, sys, datetime
from Qt import QtCore, QtGui, QtWidgets

class ValidationItem(object):
    def __init__(self, message, **kwargs):
        super(ValidationItem, self).__init__()
        self.status = kwargs.get('status', 'info')
        self.message = message


class ValidationItemModel(QtGui.QStandardItemModel):

    # Constructor
    def __init__(self):
        super(ValidationItemModel, self).__init__()
        self._items = []
        self.setHorizontalHeaderLabels(['Status', 'Message'])

    # Overrides
    def clear(self):
        self.beginResetModel()
        self._items = []
        self.endResetModel()

    def rowCount(self, parent=QtCore.QModelIndex()):
        if parent.isValid():
            return 0
        return len(self._items)

    def index(self, row, column, parent=QtCore.QModelIndex()):
        return self.createIndex(row, column, parent)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        print 'GETTING DATA'
        if not index.isValid():
            return None

        row = index.row()
        col = index.column()

        print row, col

        item = self.itemByIndex(index.row())
        if not item:
            return None

        print item    
        if role == QtCore.Qt.UserRole:
            return item

        return None

    # Methods
    def itemByIndex(self, index):
        print index
        if (index < 0 or index >= len(self._items)):
            return None
        return self._items[index]

    def appendItem(self, item):
        self.beginInsertRows(QtCore.QModelIndex(), self.rowCount(), self.rowCount())
        self._items.append(item)
        self.endInsertRows()
        print self.rowCount()


class SimpleDialog(QtWidgets.QDialog):

    def __init__(self, parent=None):
        super(SimpleDialog, self).__init__(parent=parent)
        self.resize(500,300)

        self.itemModel = ValidationItemModel()
        self.itemModel.appendItem(ValidationItem('Hello world! 1', status='warning'))
        self.itemModel.appendItem(ValidationItem('Hello world! 2', status='info'))
        self.itemModel.appendItem(ValidationItem('Hello world! 3', status='error'))
        self.itemModel.appendItem(ValidationItem('Hello world! 4', status='valid'))
        self.proxyModel = QtCore.QSortFilterProxyModel()
        self.proxyModel.setSourceModel(self.itemModel)

        self.treeView = QtWidgets.QTreeView()
        self.treeView.setModel(self.proxyModel)
        self.layout = QtWidgets.QVBoxLayout()
        self.layout.addWidget(self.treeView)
        self.setLayout(self.layout)


def main():
    app = QtWidgets.QApplication(sys.argv)
    ex = SimpleDialog()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

已更新

下面是我正在工作的更新代码。发布此代码的原因,如果是因为用户建议我在下面自定义QStandardItem而不是模型。我希望他可以用我的代码进行演示,以便我可以更好地了解如何执行此操作。需要注意的主要事情是用户可以双击一个项目,它将执行通过UserRole访问它的每个项目的run功能。

enter image description here

import os, sys, datetime
from Qt import QtCore, QtGui, QtWidgets


class ValidationItem(object):
    def __init__(self, message, **kwargs):
        super(ValidationItem, self).__init__()
        self.status = kwargs.get('status', 'info')
        self.message = message

    def run(self):
        print 'STUBBED IN METHOD', self.status, self.message


class ValidationItemURL(ValidationItem):
    def __init__(self, message, **kwargs):
        super(ValidationItem, self).__init__()
        self.status = kwargs.get('status', 'info')
        self.message = message

    def run(self):
        os.startfile('https://stackoverflow.com/')



class ValidationItemModel(QtCore.QAbstractTableModel):
    VALIDATION_STATUSES = {
        'error': QtGui.QColor(220,70,55),
        'warning': QtGui.QColor(240,180,10),
        'valid': QtGui.QColor(10,170,70)
    }


    # Constructor
    def __init__(self):
        super(ValidationItemModel, self).__init__()
        self._items = []
        self._headers = ['Status', 'Message']

    # Overrides
    def headerData(self, section, orientation, role):
        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self._headers[section]

    def flags(self, index):
        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def clear(self):
        self.beginResetModel()
        self._items = []
        self.endResetModel()

    def rowCount(self, parent=QtCore.QModelIndex()):
        if parent.isValid():
            return 0
        return len(self._items)

    def columnCount(self, parent):
        return len(self._headers)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if not index.isValid():
            return None

        item = self.itemByIndex(index.row())
        if not item:
            return None

        row = index.row()
        column = index.column()

        if role == QtCore.Qt.DisplayRole:
            if column == 0:
                return item.status.title()
            elif column == 1:
                return item.message

        elif role == QtCore.Qt.ToolTipRole:
            if column == 0:
                return item.status.title()
            elif column == 1:
                return item.message

        elif role == QtCore.Qt.ForegroundRole:
            if column == 0:
                if item.status in self.VALIDATION_STATUSES:
                    return self.VALIDATION_STATUSES[item.status]

        if role == QtCore.Qt.UserRole:
            return item

        return None

    # Methods
    def itemByIndex(self, index):
        if (index < 0 or index >= len(self._items)):
            return None
        return self._items[index]

    def appendItem(self, item):
        if isinstance(item, ValidationItem):
            self.beginInsertRows(QtCore.QModelIndex(), self.rowCount(), self.rowCount())
            self._items.append(item)
            self.endInsertRows()


class SimpleDialog(QtWidgets.QDialog):

    def __init__(self, parent=None):
        super(SimpleDialog, self).__init__(parent=parent)
        self.resize(500,300)

        self.itemModel = ValidationItemModel()
        self.itemModel.appendItem(ValidationItem('Hello world! 1', status='warning'))
        self.itemModel.appendItem(ValidationItem('Hello world! 2', status='info'))
        self.itemModel.appendItem(ValidationItem('Hello world! 3', status='error'))
        self.itemModel.appendItem(ValidationItemURL('stackoverflow (double-click to visit)', status='valid'))
        self.proxyModel = QtCore.QSortFilterProxyModel()
        self.proxyModel.setSourceModel(self.itemModel)

        self.treeView = QtWidgets.QTreeView()
        self.treeView.setModel(self.proxyModel)
        self.layout = QtWidgets.QVBoxLayout()
        self.layout.addWidget(self.treeView)
        self.setLayout(self.layout)

        # Signals
        self.treeView.doubleClicked.connect(self.slotDoubleClickedItem)


    # Slots
    def slotDoubleClickedItem(self, index):
        if index.isValid():
            item = index.data(role=QtCore.Qt.UserRole)
            if item:
                item.run()


def main():
    app = QtWidgets.QApplication(sys.argv)
    ex = SimpleDialog()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

0 个答案:

没有答案