从文本 slug 获取 QTreeview 索引
Get QTreeview index from text slug
我正在尝试使用给定的 slug 检索 QTreeView 项目的模型索引 - 它是一个字符串,表示由连字符分隔的 treeview 项目的层次结构。在这种情况下,我想获取给定 slug 'Vegetable-Carrot-Blackbean'
:
的模型索引
我当前的函数总是 returns "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()
在这种情况下,方便的方法是递归迭代子项:
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
您当前的实现不起作用的原因是 match()
的 start
参数需要是有效索引。不可见的根项永远不会有效,因为它的行和列将始终为 -1
。因此,您必须使用模型的 index() 函数来尝试获取当前父项的第一个子索引。您还需要确保当 any 部分 slug 无法匹配时 returned,否则您可以错误地结束了 returning 祖先索引。
这是实现所有这些的方法:
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]
作为替代方案,您可能需要考虑 returning 一个 项目,因为这样您就可以访问整个 QStandardItem
API(索引仍然可以通过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
但请注意,如果找不到 slug,则此 returns None
(尽管它可以很容易地调整为 return 不可见的根项目)。
我正在尝试使用给定的 slug 检索 QTreeView 项目的模型索引 - 它是一个字符串,表示由连字符分隔的 treeview 项目的层次结构。在这种情况下,我想获取给定 slug 'Vegetable-Carrot-Blackbean'
:
我当前的函数总是 returns "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()
在这种情况下,方便的方法是递归迭代子项:
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
您当前的实现不起作用的原因是 match()
的 start
参数需要是有效索引。不可见的根项永远不会有效,因为它的行和列将始终为 -1
。因此,您必须使用模型的 index() 函数来尝试获取当前父项的第一个子索引。您还需要确保当 any 部分 slug 无法匹配时 returned,否则您可以错误地结束了 returning 祖先索引。
这是实现所有这些的方法:
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]
作为替代方案,您可能需要考虑 returning 一个 项目,因为这样您就可以访问整个 QStandardItem
API(索引仍然可以通过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
但请注意,如果找不到 slug,则此 returns None
(尽管它可以很容易地调整为 return 不可见的根项目)。