Below I am giving one example.
I have two QObject derived class "Country" and "State"
State:
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged
) Q_PROPERTY(QList<QString> cmList READ cmList WRITE setCmList NOTIFY cmListChanged)
public:
{
return m_name;
}
{
m_name = val;
emit nameChanged();
}
QList<QString> cmList()
{
return m_CMList;
}
void setCmList(QList<QString> val)
{
m_CMList = val;
emit cmListChanged();
}
signals:
void nameChanged();
void cmListChanged();
private:
QList<QString> m_CMList;
};
class State : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QList<QString> cmList READ cmList WRITE setCmList NOTIFY cmListChanged)
public:
QString name()
{
return m_name;
}
void setName(QString val)
{
m_name = val;
emit nameChanged();
}
QList<QString> cmList()
{
return m_CMList;
}
void setCmList(QList<QString> val)
{
m_CMList = val;
emit cmListChanged();
}
signals:
void nameChanged();
void cmListChanged();
private:
QString m_name;
QList<QString> m_CMList;
};
To copy to clipboard, switch view to plain text mode
Country:
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged
) Q_PROPERTY(QList<QString> pmList READ pmList WRITE setPmList NOTIFY pmListChanged)
Q_PROPERTY(QQmlListProperty<State> stateList READ stateList CONSTANT)
public :
Country()
{
}
{
return m_name;
}
{
m_name = val;
emit nameChanged();
}
QList<QString> pmList()
{
return m_PMList;
}
void setPmList(QList<QString> val)
{
m_PMList = val;
emit pmListChanged();
}
QQmlListProperty<State> stateList()
{
return QQmlListProperty<State>(this, m_StateList);
}
void appendState(State* obj)
{
m_StateList.append(obj);
}
signals:
void nameChanged();
void pmListChanged();
private:
QList<QString> m_PMList;
QList<State*> m_StateList;
};
class Country : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QList<QString> pmList READ pmList WRITE setPmList NOTIFY pmListChanged)
Q_PROPERTY(QQmlListProperty<State> stateList READ stateList CONSTANT)
public :
Country()
{
}
QString name()
{
return m_name;
}
void setName(QString val)
{
m_name = val;
emit nameChanged();
}
QList<QString> pmList()
{
return m_PMList;
}
void setPmList(QList<QString> val)
{
m_PMList = val;
emit pmListChanged();
}
QQmlListProperty<State> stateList()
{
return QQmlListProperty<State>(this, m_StateList);
}
void appendState(State* obj)
{
m_StateList.append(obj);
}
signals:
void nameChanged();
void pmListChanged();
private:
QString m_name;
QList<QString> m_PMList;
QList<State*> m_StateList;
};
To copy to clipboard, switch view to plain text mode
Metatype:
Q_DECLARE_METATYPE(QQmlListProperty< Country > )
Q_DECLARE_METATYPE(QQmlListProperty< State > )
Q_DECLARE_METATYPE(QQmlListProperty< Country > )
Q_DECLARE_METATYPE(QQmlListProperty< State > )
To copy to clipboard, switch view to plain text mode
I also have "QAbstractListModel" derived model class called "MyModel"
{
Q_OBJECT
public:
MyModel();
void setList(const QList<QObject*> &list)
{
m_list = list;
}
{
m_list.length();
}
{
if(!m_list.isEmpty())
return m_list.at(0)->metaObject()->propertyCount() - m_list.at(0)->metaObject()->propertyOffset();
return 0;
}
QVariant headerData
(int section, Qt
::Orientation orientation,
int role
) const {
Q_UNUSED(section);
Q_UNUSED(orientation);
Q_UNUSED(role);
}
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles;
if(!m_list.isEmpty())
{
const QMetaObject* metaObject
= m_list.
at(0)->metaObject
();
int r = Qt::UserRole+1;
for(int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); ++i)
{
roles
[r
++] = QByteArray(metaObject
->property
(i
).
name());
}
}
return roles;
}
{
if (!index.isValid() || m_list.isEmpty())
{
}
else
{
}
role = role - Qt::UserRole;
if(role > 0 && m_list.length() > index.row())
{
const QMetaObject* metaObject
= m_list.
at(index.
row())->metaObject
();
role += metaObject->propertyOffset();
if(role <= metaObject->propertyCount())
{
return metaObject->property(role-1).read(m_list.at(index.row()));
}
}
}
private:
QList<QObject*> m_list;
};
class MyModel : public QAbstractListModel
{
Q_OBJECT
public:
MyModel();
void setList(const QList<QObject*> &list)
{
m_list = list;
}
int rowCount(const QModelIndex &parent) const
{
m_list.length();
}
int columnCount(const QModelIndex &parent) const
{
if(!m_list.isEmpty())
return m_list.at(0)->metaObject()->propertyCount() - m_list.at(0)->metaObject()->propertyOffset();
return 0;
}
QVariant headerData(int section, Qt::Orientation orientation, int role) const
{
Q_UNUSED(section);
Q_UNUSED(orientation);
Q_UNUSED(role);
return QVariant();
}
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles;
if(!m_list.isEmpty())
{
const QMetaObject* metaObject = m_list.at(0)->metaObject();
int r = Qt::UserRole+1;
for(int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); ++i)
{
roles[r++] = QByteArray(metaObject->property(i).name());
}
}
return roles;
}
QVariant data(const QModelIndex &index, int role) const
{
if (!index.isValid() || m_list.isEmpty())
{
return QVariant();
}
else
{
}
role = role - Qt::UserRole;
if(role > 0 && m_list.length() > index.row())
{
const QMetaObject* metaObject = m_list.at(index.row())->metaObject();
role += metaObject->propertyOffset();
if(role <= metaObject->propertyCount())
{
return metaObject->property(role-1).read(m_list.at(index.row()));
}
}
return QVariant();
}
private:
QList<QObject*> m_list;
};
To copy to clipboard, switch view to plain text mode
I have a QList<Country*> and I want to display it on my QML ListView.
Below I gave a small example how i am using it.
qmlRegisterType<Country>("mytest.country", 1, 0, "Country");
qmlRegisterType<State>("mytest.state", 1, 0, "State");
QList<QString> cmList;
QList<QString> pmList;
cmList << "cm1" << "cm2";
pmList << "pm1" << "pm2";
State s1, s2, s3, s4;
s1.setName("S1");
s1.setCmList(cmList);
s2.setName("S2");
s2.setCmList(cmList);
s3.setName("S3");
s3.setCmList(cmList);
s4.setName("S4");
s4.setCmList(cmList);
Country c1, c2;
c1.setName("C1");
c1.setPmList(pmList);
c1.appendState(&s1);
c1.appendState(&s2);
c2.setName("C2");
c2.setPmList(pmList);
c2.appendState(&s3);
c2.appendState(&s4);
QList<QObject*> countryList;
countryList << &c1 << & c2;
MyModel myModel;
myModel.setList(countryList);
QQmlApplicationEngine engine;
QQmlContext * context = engine.rootContext();
context->setContextProperty("myModel", &myModel);
engine.load("../test/testqml.qml");
qmlRegisterType<Country>("mytest.country", 1, 0, "Country");
qmlRegisterType<State>("mytest.state", 1, 0, "State");
QList<QString> cmList;
QList<QString> pmList;
cmList << "cm1" << "cm2";
pmList << "pm1" << "pm2";
State s1, s2, s3, s4;
s1.setName("S1");
s1.setCmList(cmList);
s2.setName("S2");
s2.setCmList(cmList);
s3.setName("S3");
s3.setCmList(cmList);
s4.setName("S4");
s4.setCmList(cmList);
Country c1, c2;
c1.setName("C1");
c1.setPmList(pmList);
c1.appendState(&s1);
c1.appendState(&s2);
c2.setName("C2");
c2.setPmList(pmList);
c2.appendState(&s3);
c2.appendState(&s4);
QList<QObject*> countryList;
countryList << &c1 << & c2;
MyModel myModel;
myModel.setList(countryList);
QQmlApplicationEngine engine;
QQmlContext * context = engine.rootContext();
context->setContextProperty("myModel", &myModel);
engine.load("../test/testqml.qml");
To copy to clipboard, switch view to plain text mode
QML:
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQml 2.0
import mytest.country 1.0
import mytest.state 1.0
ApplicationWindow {
visible: true
width: 600
height: 600
Rectangle
{
id: rect1
color: "transparent"
anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter
ScrollView
{
id: slv1
width: parent.width
height: parent.height
contentItem: listView1
focus: true
ListView
{
id: listView1
height: parent.height
width: parent.width
anchors.left: parent.left
anchors.leftMargin: 10
model: myModel
focus: true
currentIndex: 0
delegate: Item{
id: delegateRect
width: listView1.width
height: 80
Rectangle
{
width: listView1.width - 10
height: listView1.height - 10
color: "transparent"
Item
{
id: textIteml
width: 150
height:150
Text
{
anchors.verticalCenter: textIteml.verticalCenter
color: "red"
font.pointSize: 18
text: name
font.family: "corpoSLig"
width: textIteml.width
elide: Text.ElideRight
}
}
Item
{
id: textIteml1
width: 150
height:150
anchors.left: textIteml.right
anchors.leftMargin: 5
Text
{
anchors.verticalCenter: parent.verticalCenter
color: "red"
font.pointSize: 18
text: pmList[0]
font.family: "corpoSLig"
width: textIteml.width
elide: Text.ElideRight
}
}
Item
{
id: textIteml2
width: 150
height:150
anchors.left: textIteml1.right
anchors.leftMargin: 5
Text
{
anchors.verticalCenter: parent.verticalCenter
color: "red"
font.pointSize: 18
text: stateList[0] //------------------------------Error : Unable to assign [undefined] to QString
text: stateList //------------------------------Error : Unable to assign QQmlListProperty<State> to QString
//How to print 1st state name
font.family: "corpoSLig"
width: textIteml.width
elide: Text.ElideRight
}
}
}
}
}
}
}
}
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQml 2.0
import mytest.country 1.0
import mytest.state 1.0
ApplicationWindow {
visible: true
width: 600
height: 600
Rectangle
{
id: rect1
color: "transparent"
anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter
ScrollView
{
id: slv1
width: parent.width
height: parent.height
contentItem: listView1
focus: true
ListView
{
id: listView1
height: parent.height
width: parent.width
anchors.left: parent.left
anchors.leftMargin: 10
model: myModel
focus: true
currentIndex: 0
delegate: Item{
id: delegateRect
width: listView1.width
height: 80
Rectangle
{
width: listView1.width - 10
height: listView1.height - 10
color: "transparent"
Item
{
id: textIteml
width: 150
height:150
Text
{
anchors.verticalCenter: textIteml.verticalCenter
color: "red"
font.pointSize: 18
text: name
font.family: "corpoSLig"
width: textIteml.width
elide: Text.ElideRight
}
}
Item
{
id: textIteml1
width: 150
height:150
anchors.left: textIteml.right
anchors.leftMargin: 5
Text
{
anchors.verticalCenter: parent.verticalCenter
color: "red"
font.pointSize: 18
text: pmList[0]
font.family: "corpoSLig"
width: textIteml.width
elide: Text.ElideRight
}
}
Item
{
id: textIteml2
width: 150
height:150
anchors.left: textIteml1.right
anchors.leftMargin: 5
Text
{
anchors.verticalCenter: parent.verticalCenter
color: "red"
font.pointSize: 18
text: stateList[0] //------------------------------Error : Unable to assign [undefined] to QString
text: stateList //------------------------------Error : Unable to assign QQmlListProperty<State> to QString
//How to print 1st state name
font.family: "corpoSLig"
width: textIteml.width
elide: Text.ElideRight
}
}
}
}
}
}
}
}
To copy to clipboard, switch view to plain text mode
My main target is there will be a single model class and it can convert any QList<QObjetc*> to model base on the properties.
Thanks.
Bookmarks