从字符串构建 QTreeView
Building a QTreeView from strings
我正在尝试使用所谓的 slug 构建树视图:这是一个由连字符分隔的字符串(例如 Fruit-Apple
)。然后,如果该项目尚不存在,您只需遍历各个部分并构建树。列表中的第一项始终是最顶层的父项。任何建议或帮助将不胜感激。我在尝试将项目附加到正确的父项时遇到问题。
appendCategorySlug('Fruit-Apple')
appendCategorySlug('Fruit-Orange')
appendCategorySlug('Vegetable-Lettuce')
appendCategorySlug('Fruit-Kiwi')
appendCategorySlug('Vegetable-Carrot')
appendCategorySlug('Vegetable-Carrot-Blackbean')
appendCategorySlug('Vegan-Meat-Blackbean')
我不太确定这里出了什么问题。结果很接近,但有些地方不对...
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):
# sourceIndex = self.categoryProxyModel.mapToSource(proxyIndex)
# item = self.categoryModel.itemFromIndex(sourceIndex)
parts = slug.split('-')
parent = self.categoryModel.invisibleRootItem()
for name in parts:
# find part and it doesn't exist append it
items = self.categoryModel.findItems(name, QtCore.Qt.MatchExactly | QtCore.Qt.MatchRecursive, 0)
if len(items) == 1:
print items[0].data()
parent = items[0]
item = QtGui.QStandardItem(name)
parent.appendRow(item)
parent = item
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.show()
sys.exit(app.exec_())
if __name__ == '__main__':
pass
test_CategoryView()
这里有一些问题。递归搜索很容易出错,因为后代项可能与其祖先之一具有相同的名称。而且它也是低效的,因为在每一步我们只想知道在当前级别是否存在一个同名的项目——它下面的是无关紧要的。此外,我们应该避免搜索当前父级是否没有子级,并确保只有在他们丢失时才创建新的父级(这是您当前实现的主要问题)。
如果使用模型的 match function 而不是 findItems
,则可以最轻松地解决上述问题,因为它可以更好地控制搜索的完成方式:
def appendCategorySlug(self, slug):
parts = slug.split('-')
parent = self.categoryModel.invisibleRootItem()
for name in parts:
if parent.rowCount():
indexes = self.categoryModel.match(
parent.child(0).index(),
QtCore.Qt.DisplayRole, name, 1,
QtCore.Qt.MatchExactly)
if indexes:
parent = self.categoryModel.itemFromIndex(indexes[0])
continue
item = QtGui.QStandardItem(name)
parent.appendRow(item)
parent = item
这个算法可以用一个简单的for循环实现得更简单,也许更容易理解:
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
我正在尝试使用所谓的 slug 构建树视图:这是一个由连字符分隔的字符串(例如 Fruit-Apple
)。然后,如果该项目尚不存在,您只需遍历各个部分并构建树。列表中的第一项始终是最顶层的父项。任何建议或帮助将不胜感激。我在尝试将项目附加到正确的父项时遇到问题。
appendCategorySlug('Fruit-Apple')
appendCategorySlug('Fruit-Orange')
appendCategorySlug('Vegetable-Lettuce')
appendCategorySlug('Fruit-Kiwi')
appendCategorySlug('Vegetable-Carrot')
appendCategorySlug('Vegetable-Carrot-Blackbean')
appendCategorySlug('Vegan-Meat-Blackbean')
我不太确定这里出了什么问题。结果很接近,但有些地方不对...
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):
# sourceIndex = self.categoryProxyModel.mapToSource(proxyIndex)
# item = self.categoryModel.itemFromIndex(sourceIndex)
parts = slug.split('-')
parent = self.categoryModel.invisibleRootItem()
for name in parts:
# find part and it doesn't exist append it
items = self.categoryModel.findItems(name, QtCore.Qt.MatchExactly | QtCore.Qt.MatchRecursive, 0)
if len(items) == 1:
print items[0].data()
parent = items[0]
item = QtGui.QStandardItem(name)
parent.appendRow(item)
parent = item
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.show()
sys.exit(app.exec_())
if __name__ == '__main__':
pass
test_CategoryView()
这里有一些问题。递归搜索很容易出错,因为后代项可能与其祖先之一具有相同的名称。而且它也是低效的,因为在每一步我们只想知道在当前级别是否存在一个同名的项目——它下面的是无关紧要的。此外,我们应该避免搜索当前父级是否没有子级,并确保只有在他们丢失时才创建新的父级(这是您当前实现的主要问题)。
如果使用模型的 match function 而不是 findItems
,则可以最轻松地解决上述问题,因为它可以更好地控制搜索的完成方式:
def appendCategorySlug(self, slug):
parts = slug.split('-')
parent = self.categoryModel.invisibleRootItem()
for name in parts:
if parent.rowCount():
indexes = self.categoryModel.match(
parent.child(0).index(),
QtCore.Qt.DisplayRole, name, 1,
QtCore.Qt.MatchExactly)
if indexes:
parent = self.categoryModel.itemFromIndex(indexes[0])
continue
item = QtGui.QStandardItem(name)
parent.appendRow(item)
parent = item
这个算法可以用一个简单的for循环实现得更简单,也许更容易理解:
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