使用Qt 5.6 QML(升级不是一个选项)...... 我需要传递一个包含QML和C ++之间结构数组的结构(两种方式)。
// Create an object in a QML context
var workObj = objArrayComponent.createObject(mainForm)
// These things work
workObj.topParam = true
workObj.objArray = [ { someParam : true }, { someParam : false }, {someParam : true } ]
// Neither of the following work...
// After this call, the value remains false
workObj.objArray[1].someParam = true;
// After this call, the length remains 3
workObj.objArray.push( { someParam : true } )
// This works
workObj.objArray = [ { someParam : false }, { someParam : true }, {someParam : false } ]
使用以下代码,我可以使用数组创建结构的实例并传递它,但我无法修改数组的内容。我无法弄清楚我错过了什么......
#include <QObject>
#include <QVariant>
class SomeObj : public QObject
{
Q_OBJECT
public:
explicit SomeObj(QObject *parent = nullptr) : QObject(parent) {}
Q_PROPERTY( bool someParam MEMBER mSomeParam NOTIFY someParamChanged )
signals:
void someParamChanged();
public slots:
private:
bool mSomeParam;
};
class ObjArray : public QObject
{
Q_OBJECT
Q_PROPERTY( bool topParam MEMBER mTopParam NOTIFY topParamChanged )
Q_PROPERTY( QVariantList objArray MEMBER mObjArray NOTIFY objArrayChanged )
public:
explicit ObjArray(QObject *parent = nullptr) : QObject(parent) {}
signals:
void topParamChanged();
void objArrayChanged();
public slots:
private:
bool mTopParam;
QVariantList mObjArray;
};
我还尝试了一个代码版本,我拆分了READ / WRITE并创建了自己的getter / setter。我确认在设置整个workObj.objArray时调用了setter,但是没有调用其他更改。
以下完整代码......
objarray.h(没有objarray.cpp,MEMBER创建getter / setter):
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQmlComponent>
#include "objarray.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<ObjArray>("obj.array", 1, 0, "ObjArray");
qmlRegisterType<SomeObj>("some.obj", 1, 0, "SomeObj");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.cpp中:
import QtQuick 2.6
import QtQuick.Window 2.2
import obj.array 1.0
import some.obj 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
MainForm {
id: mainForm
Component {
id: objArrayComponent
ObjArray {}
}
anchors.fill: parent
mouseArea.onClicked: {
// Create an object in the form's context
var workObj = objArrayComponent.createObject(mainForm)
workObj.topParam = true
workObj.objArray = [ { someParam : true }, { someParam : false }, {someParam : true } ]
// So far so good
// results: true, (3): [true, false, true]
console.log( "results: " + workObj.topParam + ", " +
"(" + workObj.objArray.length + "): [" +
workObj.objArray[0].someParam + ", " +
workObj.objArray[1].someParam + ", " +
workObj.objArray[2].someParam + "] "
)
// This works
workObj.topParam = false
// Neither of the following work...
workObj.objArray[1].someParam = true;
workObj.objArray.push( { someParam : true } )
// Value is not changed
// Array size doesn't change
// results: false, (3): [true, false, true]
console.log( "results: " + workObj.topParam + ", " +
"(" + workObj.objArray.length + "): [" +
workObj.objArray[0].someParam + ", " +
workObj.objArray[1].someParam + ", " +
workObj.objArray[2].someParam + "] "
)
// This works
workObj.objArray = [ { someParam : false }, { someParam : true }, {someParam : false } ]
// results: false, (3): [false, true, false]
console.log( "results: " + workObj.topParam + ", " +
"(" + workObj.objArray.length + "): [" +
workObj.objArray[0].someParam + ", " +
workObj.objArray[1].someParam + ", " +
workObj.objArray[2].someParam + "] "
)
console.log(qsTr('Clicked on background. Text: "' + textEdit.text + '"'))
Qt.quit()
}
}
}
main.qml:
public:
Q_INVOKABLE void setValue( QString name, int index, bool value )
{
if( name == "someParam" )
mStoreIt[index].someParam = value;
}
Q_INVOKABLE bool getValue( QString name, int index )
{
if( name == "someParam" )
return mStoreIt[index].someParam;
}
private:
QVector<someObj> mStoreIt;
修改
显然QML变体数组无法修改,我没时间找到更好的解决方案,所以我决定采用快速的脏设置。这对于小结构来说很好,但是缩放到更大的结构将是烦人的
没有错误检查紧凑性...
<TextView
android:id="@+id/hello"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, MyActivity"
/>
答案 0 :(得分:0)
根据文件Qt site,
虽然这是存储数组和地图类型值的便捷方式,但是 必须要知道上面的项和属性属性不是 QML对象(当然也不是JavaScript对象)和 属性中的键值对不是QML属性。相反, items属性包含一组值,而属性包含一组值 键值对。因为它们存储为一组值,而不是 作为一个对象,他们的内容不能单独修改:
Item {
property variant items: [1, 2, 3, "four", "five"]
property variant attributes: { 'color': 'red', 'width': 100 }
Component.onCompleted: {
items[0] = 10
console.log(items[0]) // This will still be '1'!
attributes.color = 'blue'
console.log(attributes.color) // This will still be 'red'!
}
}