我想存储一些收入十六进制数据,出于内存效率的考虑,不希望将其转换为十六进制转义字符串。
Item {
ListModel {
id: model
}
Component.onCompleted: {
let dummyInputData = "1\x200\x00\x01234567890"
let byteArray = str2ab(tmpString)
model.append({"timestamp_utc": 1, "data": dummyInputData});
}
// Converts string to 8-bit array buffer. This is used for testing purposes
function str2ab(str) {
var buf = new ArrayBuffer(str.length);
var bufView = new Uint8Array(buf);
for (var i=0, strLen=str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
}
以上(看似)导致没有数据存储在data
中,但也没有错误。
我该怎么做呢?
我不建议尝试将ArrayBuffer直接存储到ListModel中的ListElement中。事实上,许多重要的JavaScript对象也不能存储。为了涵盖所有这些情况,我建议将它们存储在查找对象中,但将它们链接回您的ListModel,例如:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
ListView {
anchors.fill: parent
model: contacts
delegate: Frame {
ColumnLayout {
TextField { text: uid } // "BGATES"
TextField { text: gname } // "Bill"
TextField { text: sname } // "Gates"
TextField { text: contacts.extras[uid].data instanceof ArrayBuffer } // true
TextField { text: contacts.extras[uid].data.byteLength } // 23
TextArea {
implicitWidth: 300
text: JSON.stringify( contacts.extras[uid], undefined, 2)
background: Rectangle {
border.color: "#ccc"
}
}
}
}
}
ListModel {
id: contacts
property var extras: ({ })
}
function str2ab(str) {
var buf = new ArrayBuffer(str.length);
var bufView = new Uint8Array(buf);
for (var i=0, strLen=str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
Component.onCompleted: {
contacts.append({uid:"BGATES", gname:"Bill", sname:"Gates"});
contacts.extras["BGATES"] = {
data: str2ab("1\x200\x00\x01234567890"),
contact: {
address: "1 Microsoft Way",
company: "Microsoft",
},
hobbies: [ "reading", "wordle" ]
};
}
}
你可以在网上试试!
或者,如果您在这种情况下使用Qt6.4+,您可以考虑使用list<var>
代替ListModel
:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
property list<var> contacts
ListView {
anchors.fill: parent
model: contacts
delegate: Frame {
ColumnLayout {
TextField { text: modelData.uid } // "BGATES"
TextField { text: modelData.gname } // "Bill"
TextField { text: modelData.sname } // "Gates"
TextField { text: modelData.extra.data instanceof ArrayBuffer } // true
TextField { text: modelData.extra.data.byteLength } // 23
TextArea {
implicitWidth: 300
text: JSON.stringify( modelData.extra, undefined, 2)
background: Rectangle {
border.color: "#ccc"
}
}
}
}
}
function str2ab(str) {
var buf = new ArrayBuffer(str.length);
var bufView = new Uint8Array(buf);
for (var i=0, strLen=str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
Component.onCompleted: {
contacts.push( { uid: "BGATES", gname: "Bill", sname: "Gates", extra: {
data: str2ab("1\x200\x00\x01234567890"),
contact: {
address: "1 Microsoft Way",
company: "Microsoft",
},
hobbies: [ "reading", "wordle" ]
} } );
}
}
你可以在网上试试!
另外,在某些情况下,您可以简单地声明一个大的JavaScript
数组,但是,这样做的痛点是它不会对增量更新做出反应。这是不推荐的,因为,如果你使用这样的事情与ListView
每次更新数组ListView会重置因此失去任何上下文。ListModel
和list<var>
是更好的建议。