首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QListView & QIdentityProxyModel

QListView & QIdentityProxyModel
EN

Stack Overflow用户
提问于 2022-03-01 01:35:38
回答 1查看 208关注 0票数 1

我有一个QListView & QIdentityProxyModel的测试代码。

当我实现QIdentityProxyModel时,错误发生在setDatadataChanged.If的函数--我没有实现它,错误没有发生。

我试图通过PyQt6做同样的事情,但结果是一样的。

我试着用命令提示符来做,没有错误提示。

相反,我可以成功地在QTreeViewQTableView上实现QTreeView,没有问题,我一直认为QListView是这些查看器中最简单的。

我的代码中的问题在哪里?

代码语言:javascript
复制
from PySide6 import QtWidgets, QtGui, QtCore
import sys

class ListView(QtWidgets.QListView):

    def __init__(self,  parent=None):
        super(ListView, self).__init__(parent)  
         
    def insertItem(self):
         self.model().insertRows(0, 1)
         self.model().setData(self.model().index(0, 0), ListItem(text="Hallo!"))   
                
class ListItem(object):

    def __init__(self, text="", parent=None):
        super(ListItem, self).__init__()
        self.data = []
        self.text = "Hi!" if not text else text      
 
class ListModel(QtCore.QAbstractListModel):

    def __init__(self, parent=None):
        super(ListModel, self).__init__(parent)           
        self.items = []

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

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self.items)

    def headerData(self, index):
        return "LIST"

    def index(self, row, column, _parent=QtCore.QModelIndex()):    
        if row >= len(self.items) - 1:
            return QtCore.QModelIndex()
        if self.items:            
            childIndex = self.createIndex(row, column, self.items[row])      
            return childIndex
        return QtCore.QModelIndex()

    def data(self, index, role=QtCore.Qt.ItemDataRole.DisplayRole):
        if not index.isValid():
            return None
        row = index.row()
        column = index.column()
        if role == QtCore.Qt.DisplayRole:
            if 0 <= row < self.rowCount() and 0 <= column < self.columnCount():        
                return self.items[row].text
        
    def setData(self, index, value, role=QtCore.Qt.ItemDataRole.EditRole):
        if role == QtCore.Qt.ItemDataRole.EditRole:
            row = index.row()
            if 0 <= row < self.rowCount():               
                self.items[row] = value
                self.dataChanged["QModelIndex", "QModelIndex"].emit(index, index)               
                return True                          
        return False

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

    def index(self, row, column, parent=QtCore.QModelIndex()):
        if row > len(self.items) - 1:
            return QtCore.QModelIndex()
        elif self.items:            
            childIndex = self.createIndex(row, column, self.items[row])      
            return childIndex
        return QtCore.QModelIndex()

    def insertRows(self, position, rows=1, parent=QtCore.QModelIndex()):
        self.beginResetModel()
        self.beginInsertRows(parent, position, position+rows-1)
        for i in range(rows):
            self.items.insert(position+i, ListItem())
        self.endInsertRows()
        self.dataChanged["QModelIndex", "QModelIndex"].emit(parent, parent)
        self.layoutChanged.emit()
        self.endResetModel()
        return True

class ListIdentityModel(QtCore.QIdentityProxyModel):

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

    def mapFromSource(self, sourceIndex):
        if not sourceIndex.isValid():
            return QtCore.QModelIndex()        
        return self.createIndex(sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer())  

    def mapSelectionFromSource(self, selection):
        sourceIndexes = selection.indexes()
        proxySelection = QtCore.QItemSelection(sourceIndexes[0], sourceIndexes[-1])
        return proxySelection        

    def mapSelectionToSource(self, selection):
        proxyIndexes = selection.indexes()
        sourceSelection = QtCore.QItemSelection(proxyIndexes[0], proxyIndexes[-1])
        return sourceSelection    

    def mapToSource(self, proxyIndex):
        if not proxyIndex.isValid():
            return QtCore.QModelIndex()
        return self.sourceModel().createIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer())

    def setSourceModel(self, sourceModel):
        self.beginResetModel()
        super(ListIdentityModel, self).setSourceModel(sourceModel)    
        self.endResetModel()

    
def main():
    app = QtWidgets.QApplication([]) if QtWidgets.QApplication.instance() is None else QtWidgets.QApplication.instance()

    widget = QtWidgets.QWidget()
    pushbutton = QtWidgets.QPushButton("insert item")
    
    main_view = ListView()        
    model = ListModel(main_view)
    main_view.setModel(model)
    #comment or uncomment
    identity_view = ListView()
    identityModel = ListIdentityModel()
    identity_view.setModel(identityModel)
    identityModel.setSourceModel(model)
    #

    hboxlayout = QtWidgets.QHBoxLayout()    
    hboxlayout.addWidget(pushbutton)
    hboxlayout.addWidget(main_view)
    #
    hboxlayout.addWidget(identity_view)
    #
    widget.setLayout(hboxlayout)
    
    pushbutton.clicked.connect(main_view.insertItem)
    
    widget.show()
    sys.exit(app.exec())

if __name__ == "__main__":
    main()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-01 18:37:22

insertRows()函数不应该使用beginResetModel() (顾名思义,它开始了模型reset),也不应该使用layoutChanged():不仅应该始终在layoutAboutToBeChanged()后面调用它,而且只有在对模型进行排序时才应该使用该特性。

发出dataChanged()也是没有意义的,因为插入的行将导致视图对新索引调用data()

代码语言:javascript
复制
    def insertRows(self, position, rows=1, parent=QtCore.QModelIndex()):
        self.beginInsertRows(parent, position, position+rows-1)
        for i in range(rows):
            self.items.insert(position+i, ListItem())
        self.endInsertRows()
        return True

还要注意的是,您定义了两次index(),但是只有第二次使用并且实际上是正确的,这是因为if row > len(self.items) - 1:检查与前面的>=相反,这是错误的。在任何情况下,如果您使用的是QAbstractListItem,这是一个单维模型,那么绝对没有必要覆盖index(),您可以使用默认的实现。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71302836

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档