我创建了一个用于车辆电子控制单元 (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
您是否考虑过使用单个
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"
}
您可以在线尝试!