QTreeView系列文章如下,根据熟练度可以自己吃
使用QTreeView (一)。
使用QTreeView)
使用QTreeView)
PS .本文主要根据QTreeView使用(二)上的代码进行了更改!
写构想本片博客主要是解决一些在使用QTreeView中遇到的问题1,在QTreeView中使用双击信号,更改role==Qt.CheckStateRole对象时的冲突问题
2、更新树时,层次的收缩状态没有保存
3、自定义过滤器QSortFilterProxyModel的使用方法
4、QTreeView中self.selectedIndexes ()的基坑
1、左侧的checkky,如QTreeView中使用双击信号和更改role==Qt.CheckStateRole对象时的冲突问题问题描述:下图gif
def __init__(self ) : self.treeview.double clicked.connect (self.ondoubleclicked ) . defondoublecleclied 索引) :打印(有序),索引(深度)自助,索引, role ) 3360 . elif role==Qt.checkstaterole : if item.issho wis true : return Qt.checked else 3360 return Qt.unchecked role (: item=index.internal pointer ) ) if role==Qt.checkstaterole 3360 item.is show=false . else
为了避免上述问题,在定制item时需要做一点手脚
def __init__(self ) : self.is checking=true self.treeview.setitem delegate (item delegate ) self.trere self.treeview.double clicked.connect,self.ondoubleclicked, defondoubleclicked,index (3360 if self.ischeckinging 索引) classitemdelegate ) qitemdelegate ) 3360 def parent (: qitemdelegate._ _ init _ (self,parent )…self.chechech state ) : self.check distance=rect.left (-option.rect.left ) self.iconWidth=rect.width ) super ) itect.width state ) defeditorevent (自、事件、模型、选项、索引) : check rect=q rect (option.rect.left ) ) self. self.icon width (if check rect.contains (event.pos ) ) : hierarchy.is checking=true else 3360 hid th
比较一下
之前,我们设置了代理 “self.treeView.setItemDelegate(ItemDelegate(self.treeView))”,并且多了一个变量,剩下的就是在 editorEvent这个方法里面判断其是否在CheckBox的Rect内
2、刷新树时,层级的收缩状态没有保存的问题
每次都需要重新整理之前的收缩状态!十分烦!!!
做一点小手脚:
def createTree(self): self.model = FloderTreeModel(self.data) self.proxy.setSourceModel(self.model) self.isReload = True self.treeView.collapseAll() self.isReload = False if len(BluePrint.editorView.scene.hierachyItemNameIndexMap.items()) == 0: self.treeView.expandAll() else: for name, data in BluePrint.editorView.scene.expandStateDict.items(): pos = data[len(data)-1] index = self.treeView.model().index(pos[0], pos[1], self.treeView.rootIndex()) for i in range(len(data)-2, -1, -1): pos = data[i] index = self.treeView.model().index(pos[0], pos[1], index) self.treeView.expand(index) def onCollapsed(self, index): self.treeView.model().data(index, Qt.UserRole).isCollapsed = True if self.isReload is False: if BluePrint.editorView.scene.expandStateDict.get(self.treeView.model().data(index, Qt.UserRole).itemData[0], False): BluePrint.editorView.scene.expandStateDict.pop(self.treeView.model().data(index, Qt.UserRole).itemData[0]) def onExpanded(self, index): self.treeView.model().data(index, Qt.UserRole).isCollapsed = False if self.isReload is False: tempIndex = index itemPosList = [[index.row(), index.column()]] while tempIndex.parent().row() != -1 or tempIndex.parent().column() != -1: itemPosList.append([tempIndex.parent().row(), tempIndex.parent().column()]) tempIndex = tempIndex.parent() BluePrint.editorView.scene.expandStateDict[self.treeView.model().data(index, Qt.UserRole).itemData[0]] = itemPosList变化:
树收缩状态变化的时候记录下该节点的这个状态,加载的时候让这个节点重新变成该状态,这个方法很笨,但是却能解决这个问题,并且性能消耗其实也不会很多,除非树的深度及节点十分多(应该会优化的)
技巧:
1、首先将数据data给SearchFilterProxyModel,SearchFilterProxyModel给SearchFilterProxyModel,最后将SearchFilterProxyModel设置到QTreeView
2、在“filterAcceptsRow”方法中,QSortFilterProxyModel会让返回True的item显示出来,至于最重要的东西,我们可以在自定义model中先赋好值,然后通过“model().data(index, Qt.UserRole)”获取我们想要的值对象,并拿来进行判断
4、在QTreeView中QTreeView.selectedIndexes()的坑在一次使用 QTreeView.selectedIndexes() 的时候,发现返回的list长度与选中的节点数量不一致,当时的代码如下
class TreeItem(object): def __init__(self, data, parent=None, isShow=True): self.parentItem = parent self.itemData = data self.childItems = [] self.isShow = isShow self.isCollapsed = True...... def columnCount(self): return len(self.itemData) .......(详细代码往前翻之前的文章!)
之前一直没有发现的坑 这里的columeCount,因为QTreeView实际上他的列数,最多就是1,如果这里返回的值不是1,就会导致在调用 QTreeView.selectedIndexes() 的时候,返回的列表不对,比如返回的是2,那么此时返回的就会是两个item,如下图
并且,得到的QTreeView.selectedIndexes()就会是原来的两倍!因此在这里应该这么写
当然了,如果真的有需要两行,最好的建议是使用QTreeWidget这个类去继承