如何根据父ListView模型的值定义ListView模型

问题描述 投票:0回答:1

我创建了一个用于车辆电子控制单元 (ECU) 诊断的应用程序,现在我正在尝试制作一个模块来使用 Python 和 QML 读取 ECU 中的错误。 我使用两个 ListView 元素构建了一个模块:第一个 ListView 显示包含 ECU 名称的可视容器和一个子 ListView,后者依次显示该 ECU 的错误列表:

问题是我无法让每个子 ListView 使用自己单独的列表模型,并根据父 ListView 中的 ECU 名称有自己的特定错误。现在,我已经设法仅将一个常见错误列表定义为模型,这就是为什么所有子 ListView 都包含相同信息的原因。如何根据父 ListView 的委托(或该委托的模型数据)中的 ECU 名称为每个子 ListView 定义特定的列表模型?

带有列表模型的Python代码:

from PyQt6.QtCore import QObject, pyqtSlot, pyqtSignal, pyqtProperty

class DTCReading(QObject):
    def __init__(self):
        QObject.__init__(self)
        # these lists will change depending on the response of ECU, now for ease of debugging they are defined statically
        self.ecu_list = ['uBCM', 'ACU', 'ESCL']
        self.dtc_list_uBCM = ['p1230', 'u1100', 'f1441']
        self.dtc_list_ACU = ['a1111', 'b2222', 'c3333']
        self.dtc_list_ESCL = ['a1330', 'u0008', 'p1856']

    # signals
    dtc_list_emmition_signal = pyqtSignal()
    ecu_list_emmition_signal = pyqtSignal()


    # ECU list model for parent ListView
    @pyqtProperty(list, notify=ecu_list_emmition_signal)
    def ecu_list_model(self):
        return self.ecu_list 

    def ecu_list_emmition(self):
        self.ecu_list_emmition_signal.emit()

   
    # DTC list model for child ListView 
    @pyqtProperty(list, notify=dtc_list_emmition_signal)
    def dtc_list_model(self):
        return self.dtc_list_uBCM # this list-model should be different depending on the type of ECU from ECU list model

    @pyqtSlot()
    def dtc_list_emmition(self):
        self.dtc_list_emmition_signal.emit()

 

QML代码:

import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Window


Item {
    id: dtcReadingRootItem

    Rectangle {
        id: rectangle
        color: "#2c2c2c"
        border.width: 0
        anchors.fill: parent

        //parent ListView with ECU names and child ListView inside
        ListView {
            id: ecuListView
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.top: parent.top
            anchors.bottom: parent.bottom
            anchors.topMargin: 110
            anchors.bottomMargin: 10
            anchors.rightMargin: 10
            anchors.leftMargin: 10
            clip: true
            spacing: 5
            interactive: true
            Component.onCompleted: {dtc_reading_connection.dtc_reading()}

            delegate: Rectangle {
                id: ecuDelegate
                height: dtcListView.model.length * 25 + 30
                color: "#383838"
                border.color: "#fff100"
                border.width: 1
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.rightMargin: 20
                anchors.leftMargin: 0

                Label {
                    id: ecuName
                    width: 150
                    color: "#ffffff"
                    text: model.modelData
                    anchors.top: parent.top
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.topMargin: 5
                    styleColor: "#ffffff"
                    font.pointSize: 10
                    font.family: "Verdana"
                    renderType: Text.NativeRendering
                }
                
                //child ListView with error codes
                ListView {                  
                    id: dtcListView
                    height: model.length * 25
                    anchors.left: parent.left
                    anchors.right: parent.right
                    anchors.top: parent.top
                    anchors.topMargin: 25
                    anchors.rightMargin: 20
                    anchors.leftMargin: 20
                    clip: true
                    spacing: 5
                    interactive: true
                    Component.onCompleted: {dtc_reading_connection.dtc_reading()}


                    delegate: Rectangle {
                        id: dtcDelegate
                        height: 20
                        visible: true
                        color: "#fff100"
                        anchors.left: parent.left
                        anchors.right: parent.right
                        anchors.rightMargin: 0
                        anchors.leftMargin: 0
                        width: dtcListView.width-40


                        Label {
                            id: testLabel
                            width: 150
                            color: "#000000"
                            text: model.modelData
                            anchors.left: parent.left
                            anchors.right: parent.right
                            anchors.top: parent.top
                            anchors.bottom: parent.bottom
                            horizontalAlignment: Text.AlignHCenter
                            verticalAlignment: Text.AlignVCenter
                            anchors.rightMargin: 20
                            anchors.leftMargin: 20
                            anchors.bottomMargin: 20
                            anchors.topMargin: 20
                            styleColor: "#ffffff"
                            font.pointSize: 12
                            font.family: "Verdana"
                            renderType: Text.NativeRendering
                        }
                    }

                    model: {dtc_reading_connection.dtc_list_model} //I don't know how to define here different models depending on ECU name from parent ListView model data

                    ScrollBar.vertical: ScrollBar {}
                }
            }

            model: {dtc_reading_connection.ecu_list_model} //parent ListView model with ECU names

            ScrollBar.vertical: ScrollBar {}
        }
    }

我尝试设置一个新的 str 函数参数,其中包含 ECU 名称,但它不起作用,我无法从 QML 传递此 str,因此出现缺少参数错误:

@pyqtProperty(list, notify=dtc_list_emmition_signal)
def dtc_list_model(self, ecu):
    if ecu == 'uBCM':
        return self.dtc_list_uBCM
    else:
        return self.dtc_list_ACU
python windows listview qml
1个回答
0
投票

您是否考虑过使用单个

ListView
及其剖面属性?

https://doc.qt.io/qt-6/qml-qtquick-listview.html#section-prop

这是一个例子:

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
    background: Rectangle { color: "black" }
    title: "ListView sections"
    Frame {
        width: parent.width
        background: Rectangle {
            border.color: "yellow"
            color: "#555"
        }
        ListView {
            width: parent.width
            height: contentHeight
            implicitWidth: width
            implicitHeight: height
            anchors.margins: 20
            model: listModel
            delegate: ListViewDelegate { }
            section.property: "sec"
            section.delegate: ListViewSectionDelegate { }
        }
    }
    ListModel {
        id: listModel
        ListElement { sec: "uBCM"; part: "p1230" }
        ListElement { sec: "uBCM"; part: "u1100" }
        ListElement { sec: "uBCM"; part: "f1441" }
        ListElement { sec: "ACU"; part: "p1230" }
        ListElement { sec: "ACU"; part: "u1100" }
        ListElement { sec: "ACU"; part: "f1441" }
        ListElement { sec: "ESCL"; part: "p1230" }
        ListElement { sec: "ESCL"; part: "u1100" }
        ListElement { sec: "ESCL"; part: "f1441" }
    }
}

// ListViewSectionDelegate.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Label {
    width: ListView.view.width
    text: section
    horizontalAlignment: Qt.AlignHCenter
    color: "white"
    background: Item { }
    padding: 4
}

// ListViewDelegate.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Label {
    width: ListView.view.width
    text: part
    horizontalAlignment: Qt.AlignHCenter
    background: Rectangle {
        color: "yellow"
        border.color: "#555"
        border.width: 3
    }
    padding: 4
    color: "black"
}

您可以在线尝试!

© www.soinside.com 2019 - 2024. All rights reserved.