我正在python3.5上用PyQt5.7.1开发一个应用程序。我使用QTreeView以层次结构显示一些数据。我希望能够过滤这些数据,所以我使用了QSortFilterProxy模型。在
self.model = CustomTreeModel(data)
self.proxy = QSortFilterProxyModel(self.model)
self.ui.treeView.setModel(self.proxy)
这就产生了一种奇怪的行为: 默认情况下,树视图是折叠的。如果我展开任何不是第一个的项,然后单击它的任何子项,树视图的第一个项就会展开(不应该)。实际上,每当我单击任何不是第一级(根项的子项)的项时,根项的第一个子项就会展开。在
我以为我的模型有问题,但如果我不使用QSortFilterProxy模型,像这样:
^{pr2}$treeView的行为与预期一样,第一个元素在不应该展开时不会展开
在我看来,这是PyQt5中的一个bug,但我在互联网上没有找到任何关于它的信息。相反,有一些使用qstreeview的QSortFilterProxyModel的例子,似乎没有人报告这样的问题。那么这真的是PyQt中的一个bug还是我遗漏了什么?在
下面是一个演示代码:
from PyQt5.QtCore import QAbstractItemModel, QModelIndex, Qt
class CustomTreeModel(QAbstractItemModel):
# Based on http://trevorius.com/scrapbook/uncategorized/pyqt-custom-abstractitemmodel/
def __init__(self, headerData, nodes):
QAbstractItemModel.__init__(self)
self._headerData = headerData
self._root = CustomNode(None)
for node in nodes:
self._root.addChild(node)
def addChild(self, in_node, in_parent=QModelIndex()):
if not in_parent or not in_parent.isValid():
parent = self._root
else:
parent = in_parent.internalPointer()
parent.addChild(in_node)
def index(self, in_row, in_column, in_parent=QModelIndex()):
if not in_parent.isValid():
parent = self._root
else:
parent = in_parent.internalPointer()
if not QAbstractItemModel.hasIndex(self, in_row, in_column, in_parent):
return QModelIndex()
child = parent.child(in_row)
if child:
return QAbstractItemModel.createIndex(self, in_row, in_column, child)
else:
return QModelIndex()
def rowCount(self, in_index=QModelIndex()):
if in_index.isValid():
return in_index.internalPointer().childCount()
return self._root.childCount()
def child(self, row, index):
if index.isValid():
c = index.internalPointer().child(row)
return QAbstractItemModel.createIndex(self, row, 0, c)
return QModelIndex()
def parent(self, in_index):
if in_index.isValid():
p = in_index.internalPointer().parent()
if p:
return QAbstractItemModel.createIndex(self, p.row(),0,p)
return QModelIndex()
def columnCount(self, in_index):
if in_index.isValid():
return in_index.internalPointer().columnCount()
return self._root.columnCount()
def data(self, in_index, role):
if not in_index.isValid():
return None
node = in_index.internalPointer()
if role == Qt.DisplayRole:
return node.data(in_index.column())
return None
def headerData(self, section, orientation, role=Qt.DisplayRole):
if (section < 0) or (section > self.columnCount(QModelIndex())):
return None
if (orientation == Qt.Horizontal) and (role == Qt.DisplayRole):
return self._headerData[section]
return None
class CustomNode(object):
def __init__(self, in_data):
self._data = in_data
if type(in_data) == tuple:
self._data = list(in_data)
if type(in_data) == str or not hasattr(in_data, '__getitem__'):
self._data = [in_data]
self._columncount = len(self._data)
self._children = []
self._parent = None
self._row = 0
def data(self, in_column):
if in_column >= 0 and in_column < len(self._data):
return self._data[in_column]
return None
def columnCount(self):
return self._columncount
def childCount(self):
return len(self._children)
def child(self, in_row):
if in_row >= 0 and in_row < self.childCount():
return self._children[in_row]
return None
def parent(self):
return self._parent
def row(self):
return self._row
def addChild(self, in_child):
in_child._parent = self
in_child._row = len(self._children)
self._children.append(in_child)
self._columncount = max(in_child.columnCount(), self._columncount)
if __name__ == '__main__':
import sys
from PyQt5.QtCore import QSortFilterProxyModel
from PyQt5.QtWidgets import QApplication, QTreeView
app = QApplication(sys.argv)
header = ['Food']
fruits = CustomNode(['Fruit'])
fruits.addChild(CustomNode(['Apple']))
fruits.addChild(CustomNode(['Banana']))
fruits.addChild(CustomNode(['Orange']))
vegetables = CustomNode(['Vegetables'])
vegetables.addChild(CustomNode(['Carott']))
vegetables.addChild(CustomNode(['Potato']))
meat = CustomNode(['Meat'])
meat.addChild(CustomNode(['Beef']))
meat.addChild(CustomNode(['Chicken']))
meat.addChild(CustomNode(['Pork']))
nodes = [fruits, vegetables, meat]
v = QTreeView()
model = CustomTreeModel(header, nodes)
proxy = QSortFilterProxyModel()
proxy.setSourceModel(model)
v.setModel(proxy)
v.show()
sys.exit(app.exec_())
目前没有回答
相关问题 更多 >
编程相关推荐