Reputation: 303
I'm trying to rewrite interface for a Qt-Android program from QWidgets to QML. I never used it earlier so mistakes could be very obvious and dumb.
New interface is based on ListView:
It looks like:
ListView
{
id: listView
x: 16
y: 146
width: 262
height: 282
model: myModel
delegate: Item
{
x: 5
width: 80
height: 40
Row
{
id: row1
spacing: 10
Text
{
width: 50
text:model.modelData.getPassword
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
ProgressBar
{
value: model.modelData.getDifficulty
}
}
}
}
List in main() is filled this way:
QList<QObject*> dataList;
dataList.append(new DataObject("Item 1", 50));
dataList.append(new DataObject("Item 2", 60));
dataList.append(new DataObject("Item 3", 70));
dataList.append(new DataObject("Item 4", 80));
QGuiApplication app(argc, argv);
qmlRegisterType<BackEnd>("tk.asciigames.backend", 1, 0, "BackEnd");
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("myModel", QVariant::fromValue(dataList));
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
DataObject:
class DataObject : public QObject
{
Q_OBJECT
Q_PROPERTY(QString password READ getPassword)
Q_PROPERTY(unsigned int difficulty READ getDifficulty)
public:
DataObject(QString _pass, unsigned int _difficulty)
{
difficulty = _difficulty;
password = _pass;
}
QString getPassword()
{
return password;
}
unsigned int getDifficulty()
{
return difficulty;
}
private:
unsigned int difficulty;
QString password;
};
While running QML really shows 4 lines(as expected) but without data. Log has such errors:
qrc:/main.qml:118:26: Unable to assign [undefined] to QString
qrc:/main.qml:124:28: Unable to assign [undefined] to double
Those errors corresponds to QML-lines:
text:model.modelData.getPassword
value: model.modelData.getDifficulty
So it looks like QML gets the array but not able to get data from it.
Can somebody help me to find a mistake?
Upvotes: 5
Views: 17152
Reputation: 5326
When you declare the Q_PROPERTY, you define a name, and a getter function. The getter function is used by the c++ to get the actual value of the property, but the QML engine has no knowledge of it ; it only knows the property name (password
in this example)
Q_PROPERTY(QString password READ getPassword)
So, in your QML file, change the lines
text:model.modelData.getPassword
value: model.modelData.getDifficulty
to
text:model.modelData.password
value: model.modelData.difficulty
And you should be good to go.
Note that you can also use a shortened syntax to access the properties
value: model.modelData.difficulty // OK
value: model.difficulty // OK
value: modelData.difficulty // OK
value: difficulty // Still OK
value: model.model.model.model.model.modelData.difficulty // OK, but don't do that
You may also want to flag your Q_PROPERTY as CONSTANT, to get rid of the warning QQmlExpression: Expression qrc:/main.qml:25:20 depends on non-NOTIFYable properties:
Q_PROPERTY(QString password READ getPassword CONSTANT)
Upvotes: 7