Thanks, anda_skoa!
That's exactly what I did - and it works! I have a rather complex model with several lists in it and it was not easy to get it done, but here are a few details for others with the same problem. This is not a compileable example (too big), it may have been shortened too much and may contain simplification mistakes - but it might perhaps be able to shorten the solution finding process of others anyway.
I need several buttons, each with several data fields on it. The latter are defined here:
class DataFieldContent
: public QObject{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged
) Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged
) signals:
void textChanged();
void colorChanged();
public:
[...]
//getters
//setters
};
class DataFieldContent: public QObject
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
signals:
void textChanged();
void colorChanged();
public:
[...]
//getters
QString text();
QColor color();
//setters
void setText(QString text);
void setColor(QColor color);
};
To copy to clipboard, switch view to plain text mode
All my data fields are organized in a C++ class "Content":
{
Q_OBJECT
Q_PROPERTY(QQmlListProperty<DataFieldContent>dataFieldContents READ dataFieldContents NOTIFY dataFieldContentsChanged)
signals:
void dataFieldContentsChanged();
public:
[...]
QQmlListProperty<DataFieldContent> dataFieldContents() { return
QQmlListProperty<DataFieldContent> (this,
0,
&appendDataFieldContent,
&dataFieldContentsCount,
&dataFieldContentAt,
&dataFieldContentsClear);
}
static void appendDataFieldContent(QQmlListProperty<DataFieldContent> *list, DataFieldContent *p);
static int dataFieldContentsCount(QQmlListProperty<DataFieldContent> *list);
static DataFieldContent* dataFieldContentAt(QQmlListProperty<DataFieldContent> *list, int i);
static void dataFieldContentsClear(QQmlListProperty<DataFieldContent> *list);
protected:
QList<DataFieldContent*>m_dataFieldContents;
class Content: public QObject
{
Q_OBJECT
Q_PROPERTY(QQmlListProperty<DataFieldContent>dataFieldContents READ dataFieldContents NOTIFY dataFieldContentsChanged)
signals:
void dataFieldContentsChanged();
public:
[...]
QQmlListProperty<DataFieldContent> dataFieldContents() { return
QQmlListProperty<DataFieldContent> (this,
0,
&appendDataFieldContent,
&dataFieldContentsCount,
&dataFieldContentAt,
&dataFieldContentsClear);
}
static void appendDataFieldContent(QQmlListProperty<DataFieldContent> *list, DataFieldContent *p);
static int dataFieldContentsCount(QQmlListProperty<DataFieldContent> *list);
static DataFieldContent* dataFieldContentAt(QQmlListProperty<DataFieldContent> *list, int i);
static void dataFieldContentsClear(QQmlListProperty<DataFieldContent> *list);
protected:
QList<DataFieldContent*>m_dataFieldContents;
To copy to clipboard, switch view to plain text mode
As I need a bunch of those Buttons, there is also a GroupContent, basically a List of Contents (Note that QList does not derive from QObject, you can't "just use" it).
{
Q_OBJECT
Q_PROPERTY(QQmlListProperty<Content> contents READ contents NOTIFY contentsChanged)
signals:
void contentsChanged();
public slots:
void contentsChangedSlot();
public:
[...]
QQmlListProperty <Content> contents();
static void appendContent(QQmlListProperty<Content> *list, Content *p);
static int contentsCount(QQmlListProperty<Content>*list);
static Content* contentAt(QQmlListProperty<Content> *list, int i);
static void contentsClear(QQmlListProperty<Content> *list);
void addContent(Content* p) { m_Contents.append(p);}
protected:
QList<Content*> m_Contents;
};
class GroupContent: public QObject
{
Q_OBJECT
Q_PROPERTY(QQmlListProperty<Content> contents READ contents NOTIFY contentsChanged)
signals:
void contentsChanged();
public slots:
void contentsChangedSlot();
public:
[...]
QQmlListProperty <Content> contents();
static void appendContent(QQmlListProperty<Content> *list, Content *p);
static int contentsCount(QQmlListProperty<Content>*list);
static Content* contentAt(QQmlListProperty<Content> *list, int i);
static void contentsClear(QQmlListProperty<Content> *list);
void addContent(Content* p) { m_Contents.append(p);}
protected:
QList<Content*> m_Contents;
};
To copy to clipboard, switch view to plain text mode
On the QML side we need a display: MyButton.qml:
Item {
id: ButtonBasis
property var dataFields;
Grid {
[...]
Repeater {
id: dataFieldRepeater
model: ButtonBasis.dataFields
Text {
text: dataFieldRepeater.model[index].text
color: dataFieldRepeater.model[index].color
[...]
}
}
}
}
Item {
id: ButtonBasis
property var dataFields;
Grid {
[...]
Repeater {
id: dataFieldRepeater
model: ButtonBasis.dataFields
Text {
text: dataFieldRepeater.model[index].text
color: dataFieldRepeater.model[index].color
[...]
}
}
}
}
To copy to clipboard, switch view to plain text mode
And all that is linked together in main.qml:
Repeater {
id: contentRepeater
model: groupContent.contents
delegate: MyButton {
dataFields: contentRepeater.model[index].dataFieldContents
[...]
}
}
Repeater {
id: contentRepeater
model: groupContent.contents
delegate: MyButton {
dataFields: contentRepeater.model[index].dataFieldContents
[...]
}
}
To copy to clipboard, switch view to plain text mode
Don't forget to register your classes to QML (e.g. in main.cpp) by:
qmlRegisterType<DataFieldContent>("de.yourdomain.whatsoever.whatsoever",2,0,"DataFieldContent");
qmlRegisterType<Content>("de.yourdomain.whatsoever.whatsoever",2,0,"Content");
qmlRegisterType<GroupContent>("de.yourdomain.whatsoever.whatsoever",2,0,"GroupContent");
qmlRegisterType<DataFieldContent>("de.yourdomain.whatsoever.whatsoever",2,0,"DataFieldContent");
qmlRegisterType<Content>("de.yourdomain.whatsoever.whatsoever",2,0,"Content");
qmlRegisterType<GroupContent>("de.yourdomain.whatsoever.whatsoever",2,0,"GroupContent");
To copy to clipboard, switch view to plain text mode
Bookmarks