QAbstractItemModel:QTreeView中令人讨厌的分支行 [英] QAbstractItemModel: annoying branch line in QTreeView

查看:108
本文介绍了QAbstractItemModel:QTreeView中令人讨厌的分支行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了一个QAbstractItemModel的简约子类.它可以工作,但是在QTreeView中有一个奇数的分支行,不应在此处出现(因为[Sensor arrays]节之后没有更多的项目了).您不能告诉我,我做错了什么以及如何解决?

I've made a minimalistic subclass of QAbstractItemModel. It works, but in QTreeView there is a odd branch line that should not appear here (because there is no more items after [Sensor arrays] section). Cannot you tell me, what have I done wrong and how to fix it?

这是我的代码:

import os, sys

from PyQt5 import QtCore, QtGui, QtWidgets

import treelib


class BlockHierarchyNode(object):
    def __init__(self, icon_path=None, name="", description="", is_category=False):
        if icon_path is not None:
            self._icon = QtGui.QPixmap(icon_path)
            if self._icon.size() == QtCore.QSize():  # zero size (loading error)
                assert False

        else:
            self._icon = None

        self._is_category = bool(is_category)
        self._name = str(name)
        self._description = str(description)

    @property
    def icon(self):
        return self._icon

    @property
    def is_category(self):
        return self._is_category

    @property
    def name(self):
        return self._name

    @property
    def description(self):
        return self._description

    def __str__(self):
        if self.is_category:
            return "[%s]" % self.name
        else:
            return self.name


class AvailableBlocksModel(QtCore.QAbstractItemModel):
    def __init__(self, data_tree, parent=None):
        super(AvailableBlocksModel, self).__init__(parent)

        self._tree = data_tree
        assert isinstance(data_tree, treelib.Tree)

    def columnCount(self, parent_index):
        if parent_index.isValid():
            return 1
        else:
            return 1

    def rowCount(self, parent_index):
        if parent_index.isValid():
            return len(self._tree.children(parent_index.internalPointer().identifier))
        else:  # root node
            return 1

    def data(self, index, role):

        if not index.isValid():
            return None

        if role == QtCore.Qt.DisplayRole:
            return str(index.internalPointer().data)
        elif role == QtCore.Qt.DecorationRole:
            icon = index.internalPointer().data.icon
            if icon is not None:
                return icon

        return None

    def index(self, row, column, parent=QtCore.QModelIndex()):
        if not self.hasIndex(row, column, parent):
            return QtCore.QModelIndex()
        if parent.isValid():
            parent_node = parent.internalPointer()
            children = self._tree.children(parent_node.identifier)
            return self.createIndex(row, column, children[row])
        else:
            return self.createIndex(row, column, self._tree.nodes[self._tree.root])

    def parent(self, index):
        if not index.isValid():
            return QtCore.QModelIndex()

        child_item = index.internalPointer()
        parent_item = self._tree.parent(child_item.identifier)

        if parent_item is None:
            return QtCore.QModelIndex()

        parent_row = 0
        siblings = self._tree.siblings(parent_item.identifier)
        for i, elm in enumerate(siblings):
            if elm == parent_item:
                parent_row = i

        return self.createIndex(parent_row, 0, parent_item)


class MegaTree(treelib.Tree):
    def add_block_node(self, data_block, identifier=None, parent_node=None):
        id = identifier if identifier is not None else data_block.name
        if parent_node is None:
            return self.create_node(str(data_block), id, data=data_block)
        else:
            return self.create_node(str(data_block), id, data=data_block, parent=parent_node.identifier)

    @staticmethod
    def create_demo_tree():
        tree = MegaTree()
        root_data = BlockHierarchyNode(name="All blocks", is_category=True)
        root_node = tree.add_block_node(root_data, "root")  # root node


        waveforms_data = BlockHierarchyNode(name="Waveforms", is_category=True)
        waveforms_node = tree.add_block_node(waveforms_data, parent_node=root_node)

        rect_waveform_data = BlockHierarchyNode(name="Rectangular waveform", is_category=False)
        rect_waveform_node = tree.add_block_node(rect_waveform_data, parent_node=waveforms_node)

        lfm_waveform_data = BlockHierarchyNode(name="LFM waveform", is_category=False)
        lfm_waveform_node = tree.add_block_node(lfm_waveform_data, parent_node=waveforms_node)

        phasecoded_waveform_data = BlockHierarchyNode(name="Phase coded waveform", is_category=False)
        phasecoded_waveform_node = tree.add_block_node(phasecoded_waveform_data, parent_node=waveforms_node)


        sensor_array_data = BlockHierarchyNode(name="Sensor arrays", is_category=True)
        sensor_array_node = tree.add_block_node(sensor_array_data, parent_node=root_node)

        ura_data = BlockHierarchyNode(name="URA", is_category=False)
        ura_node = tree.add_block_node(ura_data, parent_node=sensor_array_node)

        ula_data = BlockHierarchyNode(name="ULA", is_category=False)
        ula_node = tree.add_block_node(ula_data, parent_node=sensor_array_node)

        return tree


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    model = AvailableBlocksModel(MegaTree.create_demo_tree())

    view = QtWidgets.QTreeView()

    view.setModel(model)
    view.expandAll()
    view.show()

    sys.exit(app.exec_())

推荐答案

哦,我只是忘记了treelibTree类的siblings方法严格给出了节点的兄弟姐妹(没有节点)本身在列表中).因此,在parent方法中,其行始终为0.=(

Oh, I've just forgotten that the siblings method of Tree class of treelib gives strictly the siblings of a node (without the node itself in the list). So, in parent method its row was always 0. = (

现在方法在这里:

def parent(self, index):
    if not index.isValid():
        return QtCore.QModelIndex()

    child_item = index.internalPointer()
    parent_item = self._tree.parent(child_item.identifier)

    if parent_item is None:
        return QtCore.QModelIndex()

    if parent_item.is_root():
        parent_row = 0
    else:
        siblings = self._tree.children(parent_item.bpointer)
        for i, elm in enumerate(siblings):
            if elm == parent_item:
                parent_row = i

这篇关于QAbstractItemModel:QTreeView中令人讨厌的分支行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆