QHBarModelMapper和QBStractItemModel行编号

2024-04-25 23:08:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python和Qt的初学者,这是我在这个论坛上的第一个问题,对我的学习过程有很大帮助。你知道吗

我将一些层次结构数据存储在qabstractemodel中,它在QTreeView中运行良好。我还成功地使用了QDataWidgetMapper和选择Model.currentChanged将选定节点的数据映射到lineEdit。你知道吗

对于某些节点,我有4列要在条形图中绘制为条形图。你知道吗

我制作了一个用于硬编码集的图表视图,但是当我添加一个QHBarModelMapper将所选行的列1-4映射到条形图序列时,我得到了一个空图表。你知道吗

import sys
from PySide2.QtCore import (QModelIndex, Qt, QObject, QAbstractItemModel)
from PySide2.QtWidgets import (QWidget, QTreeView, QLineEdit, QVBoxLayout, QApplication, QDataWidgetMapper)
from PySide2.QtCharts import QtCharts


class CustomTreeModel(QAbstractItemModel):
    def __init__(self, root, parent=None):
        super(CustomTreeModel, self).__init__(parent)
        self._root_node = root

    def rowCount(self, parent):
        if not parent.isValid():
            parent_node = self._root_node
        else:
            parent_node = parent.internalPointer()

        return parent_node.childCount()

    def columnCount(self, parent):
        return 5

    def data(self, index, role):
        if not index.isValid():
            return None

        node = index.internalPointer()

        if role == Qt.DisplayRole or role == Qt.EditRole:
            if not isinstance(node, QModelIndex):
                if index.column() == 0:
                    return node.name
                if index.column() == 1:
                    return node.value1
                if index.column() == 2:
                    return node.value2
                if index.column() == 3:
                    return node.value3
                if index.column() == 4:
                    return node.value4

    def headerData(self, section, orientation, role):
        if role == Qt.DisplayRole:
            if section == 0:
                return self._root_node.name
            if section == 1:
                return "value1"
            if section == 2:
                return "value2"
            if section == 3:
                return "value3"
            if section == 4:
                return "value4"

    def parent(self, index):
        node = self.getNode(index)
        parent_node = node.parent

        if parent_node == self._root_node:
            return QModelIndex()

        return self.createIndex(parent_node.row(), 0, parent_node)

    def index(self, row, column, parent):

        parent_node = self.getNode(parent)
        child_item = parent_node.child(row)

        if child_item:
            return self.createIndex(row, column, child_item)
        else:
            return QModelIndex()

    def getNode(self, index):
        if index.isValid():
            node = index.internalPointer()
            if node:
                return node

        return self._root_node


class Nodes(QObject):
    def __init__(self, name, value1, value2, value3, value4, parent = QModelIndex):
        self.parent = parent
        self.name = name
        self.value1 = value1
        self.value2 = value2
        self.value3 = value3
        self.value4 = value4
        self.children = []

    def child(self, row):
        return self.children[row]

    def row(self):
        if self.parent is not None:
            return self.parent.children.index(self)

    def addChild(self, child):
        self.children.append(child)

    def removeChild(self, position):
        if position > 0 or position > len(self.children):
            return False
        node = self.children.pop(position)
        node.parent = None

    def childCount(self):
        return len(self.children)

class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.line_edit = QLineEdit()
        self.tree_view = QTreeView()

        self.bar_chart = QtCharts.QChart()
        self.bar_series = QtCharts.QBarSeries()

        self.bar_chart.addSeries(self.bar_series)

        categories = ["value 1", "value 2", "value 3", "value 4"]

        axis_x = QtCharts.QBarCategoryAxis()
        axis_x.append(categories)
        self.bar_chart.addAxis(axis_x, Qt.AlignBottom)
        self.bar_series.attachAxis(axis_x)

        axis_y = QtCharts.QValueAxis()
        self.bar_chart.addAxis(axis_y, Qt.AlignLeft)
        self.bar_series.attachAxis(axis_y)

        self.chart_view = QtCharts.QChartView(self.bar_chart)
        self.chart_view.setMinimumSize(640, 480)

        self.v_layout = QVBoxLayout(self)
        self.v_layout.addWidget(self.line_edit)
        self.v_layout.addWidget(self.tree_view)
        self.v_layout.addWidget(self.chart_view)

        self.mapper = None
        self.bar_mapper = None

    def set_selection(self, current, old):
        parent = current.parent()
        self.mapper.setRootIndex(parent)
        self.mapper.setCurrentModelIndex(current)
        self.bar_mapper.setFirstBarSetRow(current.row())

    def set_model(self, model):
        self.tree_view.setModel(model)
        self.tree_view.selectionModel().currentChanged.connect(self.set_selection)

        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(model)
        self.mapper.addMapping(self.line_edit, 0)

        self.bar_mapper = QtCharts.QHBarModelMapper()
        self.bar_mapper.setModel(model)
        self.bar_mapper.setFirstColumn(1)
        self.bar_mapper.setColumnCount(4)
        self.bar_mapper.setSeries(self.bar_series)


if __name__ == "__main__":
    # Qt Application

    app = QApplication(sys.argv)

    root_node = Nodes('Data Tree', 0,0,0,0)
    node1 = Nodes('node 1', 23, 54, 35 ,35, root_node)
    node1_1 = Nodes('node 1.1', 23 , 24 , 25 , 26, node1)
    node1_2 = Nodes('node 1.2', 24, 25, 26, 23, node1)
    node2 = Nodes('node 2', 26, 27, 22, 24, root_node)
    node2_1 = Nodes('node 2.1', 25, 26, 23, 24, node2)
    node2_2 = Nodes('node 2.2', 26, 23, 24, 25, node2)
    node1.addChild(node1_1)
    node1.addChild(node1_2)
    node2.addChild(node2_1)
    node2.addChild(node2_2)
    root_node.addChild(node1)
    root_node.addChild(node2)

    data_model = CustomTreeModel(root_node)

    widget = MyWidget()
    widget.set_model(data_model)

    widget.show()
    sys.exit(app.exec_())

我意识到qabstractemodel树的行号在树中的每个父级之后重新启动。这是否意味着我不能像这样直接在这个模型上使用QHBarModelMapper:

self.bar_mapper.setFirstBarSetRow(current.row()). 

我应该用什么来代替?你知道吗


Tags: selfnodeindexreturnifdefbarroot
1条回答
网友
1楼 · 发布于 2024-04-25 23:08:18

不幸的是,尽管Q{X}ModelMapper类的文档表明它们支持qabstractemodel作为模型,但它们只能处理列表或表类型模型或树类型模型的第一层。与QListView、QDataWidgetMapper等不同,您可以通过rootIndex属性设置迭代点,但Q{X}ModelMapper的情况并非如此。你知道吗

一个可能的解决方案是实现一个代理来提取一个子树,但在您的特殊情况下,我认为它是不必要的,因为它足以遍历行:

def set_selection(self, current, old):
    parent = current.parent()
    self.mapper.setRootIndex(parent)
    self.mapper.setCurrentModelIndex(current)

    model = self.tree_view.model()
    if isinstance(model, CustomTreeModel):
        node = model.getNode(current)
        self.bar_series.clear()
        bar_set = QtCharts.QBarSet(node.name)
        bar_set << node.value1 << node.value2 << node.value3 << node.value4
        self.bar_series.append(bar_set)
        axs = self.bar_chart.axes(Qt.Vertical, self.bar_series)
        if axs:
            axis_y = axs[0]
            axis_y.setMax(max([bar_set.at(i) for i in range(bar_set.count())]) + 10)

def set_model(self, model):
    self.tree_view.setModel(model)
    self.tree_view.selectionModel().currentChanged.connect(self.set_selection)

    self.mapper = QDataWidgetMapper()
    self.mapper.setModel(model)
    self.mapper.addMapping(self.line_edit, 0)

相关问题 更多 >