我正在尝试使用给定的Slug检索QTreeView项的模型索引-这是一个单个字符串,表示树状视图项的层次结构,由连字符分隔。在这种情况下,我想获取给定子弹'Vegetable-Carrot-Blackbean'
的模型索引:
我当前的函数总是返回“ Vegetable”,我感觉它的编写方式希望它不断循环遍历给定索引的子代直到失败,返回最后找到的树项:
import os, sys
from Qt import QtWidgets, QtGui, QtCore
class CategoryView(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.resize(250,400)
self.categoryModel = QtGui.QStandardItemModel()
self.categoryModel.setHorizontalHeaderLabels(['Items'])
self.categoryProxyModel = QtCore.QSortFilterProxyModel()
self.categoryProxyModel.setSourceModel(self.categoryModel)
self.categoryProxyModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.categoryProxyModel.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.categoryProxyModel.setDynamicSortFilter(True)
self.uiTreeView = QtWidgets.QTreeView()
self.uiTreeView.setModel(self.categoryProxyModel)
self.uiTreeView.sortByColumn(0, QtCore.Qt.AscendingOrder)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.uiTreeView)
self.setLayout(self.layout)
def appendCategorySlug(self, slug):
parts = slug.split('-')
parent = self.categoryModel.invisibleRootItem()
for name in parts:
for row in range(parent.rowCount()):
child = parent.child(row)
if child.text() == name:
parent = child
break
else:
item = QtGui.QStandardItem(name)
parent.appendRow(item)
parent = item
def getIndexBySlug(self, slug):
parts = slug.split('-')
index = QtCore.QModelIndex()
if not parts:
return index
root = self.categoryModel.index(0, 0)
for x in parts:
indexes = self.categoryModel.match(root, QtCore.Qt.DisplayRole, x, 1, QtCore.Qt.MatchExactly)
if indexes:
index = indexes[0]
root = index
print index, index.data()
return index
def test_CategoryView():
app = QtWidgets.QApplication(sys.argv)
ex = CategoryView()
ex.appendCategorySlug('Fruit-Apple')
ex.appendCategorySlug('Fruit-Orange')
ex.appendCategorySlug('Vegetable-Lettuce')
ex.appendCategorySlug('Fruit-Kiwi')
ex.appendCategorySlug('Vegetable-Carrot')
ex.appendCategorySlug('Vegetable-Carrot-Blackbean')
ex.appendCategorySlug('Vegan-Meat-Blackbean')
ex.getIndexBySlug('Vegetable-Carrot-Blackbean')
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
pass
test_CategoryView()
答案 0 :(得分:1)
在这种情况下,便捷的方法是递归地遍历子级:
def getIndexBySlug(self, slug):
parts = slug.split("-")
index = QtCore.QModelIndex()
if not parts:
return index
for part in parts:
found = False
for i in range(self.categoryModel.rowCount(index)):
ix = self.categoryModel.index(i, 0, index)
if ix.data() == part:
index = ix
found = True
if not found:
return QtCore.QModelIndex()
return index
答案 1 :(得分:1)
您当前的实现不起作用的原因是start
的{{1}}参数需要是有效的索引。看不见的根项目永远不会有效,因为其行和列将始终为match()
。因此,您必须使用模型的index()函数来尝试获取当前父级的第一个子级索引。您还需要确保在子段的 任何 部分无法匹配时,返回无效索引,否则您可能会错误地返回祖先索引。
这是一种实现所有功能的方法:
-1
或者,您可能要考虑返回一个 item ,因为那样您就可以访问整个def getIndexBySlug(self, slug):
parts = slug.split('-')
indexes = [self.categoryModel.invisibleRootItem().index()]
for name in parts:
indexes = self.categoryModel.match(
self.categoryModel.index(0, 0, indexes[0]),
QtCore.Qt.DisplayRole, name, 1,
QtCore.Qt.MatchExactly)
if not indexes:
return QtCore.QModelIndex()
return indexes[0]
API(并且仍然可以轻松获取索引)通过QStandardItem
):
item.index()
但是请注意,如果找不到该段子,它将返回def itemFromSlug(self, slug):
item = None
parent = self.categoryModel.invisibleRootItem()
for name in slug.split('-'):
for row in range(parent.rowCount()):
item = parent.child(row)
if item.text() == name:
parent = item
break
else:
item = None
break
return item
(尽管可以很容易地对其进行调整以返回不可见的根项)。