从文本段中获取QTreeview索引

时间:2019-08-23 18:48:00

标签: python search pyside qtreeview

我正在尝试使用给定的Slug检索QTreeView项的模型索引-这是一个单个字符串,表示树状视图项的层次结构,由连字符分隔。在这种情况下,我想获取给定子弹'Vegetable-Carrot-Blackbean'的模型索引:

enter image description here

我当前的函数总是返回“ 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()

2 个答案:

答案 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 (尽管可以很容易地对其进行调整以返回不可见的根项)。