[英]Expose QList<QObject *> hierarchy to QML
I'm currently in the situation, that I have a QList with MyClass also including a list QList. 我目前处于这种情况,我有一个带有MyClass的QList,还包括一个列表QList。
To display this list-hierarchy I want to provide a Repeater within a ListView. 为了显示此列表层次结构,我想在ListView中提供一个Repeater。
I tried this with a QStringList and it works fine (see uncommented lines below). 我用QStringList进行了尝试,它工作正常(请参见下面的未注释行)。 When I try to do this with my QList I cannot access the name-property of MySubClass. 当我尝试使用QList进行此操作时,无法访问MySubClass的名称属性。 Instead the name-property of MyClass is shown. 而是显示MyClass的名称属性。
WRONG output: 错误输出:
Object 1
Object 1
Object 1
Object 2
Correct output should be: 正确的输出应为:
Object 1
SubObject 1
SubObject 2
Object 2
EDIT: 08.12.2014 I found out, why the sublist did not work. 编辑:08.12.2014我发现,为什么子列表不起作用。 I just had to replace one line in the delegate of the sub-ListView (name -> modelData.name). 我只需要替换子ListView的委托中的一行(名称-> modelData.name)。
Here's my code: 这是我的代码:
main.cpp main.cpp中
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QList>
#include <QDebug>
#include "myclass.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
/* create simple stringlist */
QStringList dataList;
dataList << "Data 1"
<< "Data 2"
<< "Data 3";
/* create more complex QObject List */
MySubClass *mySubObject = NULL;
QList<QObject *> mySubList;
mySubObject = new MySubClass;
mySubObject->setName("SubObject 1");
mySubList.append(mySubObject);
mySubObject = new MySubClass;
mySubObject->setName("SubObject 2");
mySubList.append(mySubObject);
/* create object list */
MyClass *myObject = NULL;
QList<QObject *> myList;
myObject = new MyClass;
myObject->setName("Object 1");
myObject->setDataList(dataList);
myObject->setObjectList(mySubList);
myList.append(myObject);
myObject = new MyClass;
myObject->setName("Object 2");
myObject->setDataList(dataList);
myList.append(myObject);
qDebug () << myList.size();
myObject = NULL;
/* start engine and expose object list */
QQmlApplicationEngine engine;
QQmlContext *myContext = engine.rootContext();
myContext->setContextProperty("myObjectList", QVariant::fromValue(myList));
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
return app.exec();
}
MyClass.h MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#include <QStringList>
#include "mysubclass.h"
class MyClass : public QObject
{
Q_OBJECT
Q_PROPERTY (QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY (QStringList dataList READ dataList WRITE setDataList NOTIFY dataListChanged)
Q_PROPERTY (QList<QObject *> objectList READ objectList WRITE setObjectList NOTIFY objectListChanged)
public:
inline MyClass(QObject *parent = 0) : QObject(parent) {}
inline ~MyClass() {}
QString name() const
{
return m_name;
}
QStringList dataList() const
{
return m_dataList;
}
QList<QObject *> objectList() const
{
return m_objectList;
}
public slots:
void setName(QString arg)
{
if (m_name != arg) {
m_name = arg;
emit nameChanged(arg);
}
}
void setDataList(QStringList arg)
{
if (m_dataList != arg) {
m_dataList = arg;
emit dataListChanged(arg);
}
}
void setObjectList(QList<QObject *> arg)
{
if (m_objectList != arg) {
m_objectList = arg;
emit objectListChanged(arg);
}
}
signals:
void nameChanged(QString arg);
void dataListChanged(QStringList arg);
void objectListChanged(QList<QObject *> arg);
private:
QString m_name;
QStringList m_dataList;
QList<QObject *> m_objectList;
};
#endif // MYCLASS_H
MySubClass.h MySubClass.h
#ifndef MYSUBCLASS_H
#define MYSUBCLASS_H
#include <QObject>
#include <QString>
class MySubClass : public QObject
{
Q_OBJECT
Q_PROPERTY (QString name READ name WRITE setName NOTIFY nameChanged)
public:
inline MySubClass(QObject *parent = 0) : QObject(parent) {}
inline ~MySubClass() {}
QString name() const
{
return m_name;
}
public slots:
void setName(QString arg)
{
if (m_name != arg) {
m_name = arg;
emit nameChanged(arg);
}
}
signals:
void nameChanged(QString arg);
private:
QString m_name;
};
#endif // MYSUBCLASS_H
main.qml main.qml
import QtQuick 2.2
import QtQuick.Window 2.1
Window {
visible: true
width: 360
height: 360
ListView {
id: view
anchors.fill: parent
model: myObjectList
delegate: Item {
width: parent.width
height: col.height
Column {
id: col
Text {
id: nameLabel
text: name
}
Repeater {
id: dataView
// model: dataList
model: objectList
delegate: Text {
id: dataLabel
// text: modelData
// text: name
/* Here's the fix!!! (dunno why, but it works) */
text: modelData.name
}
}
}
}
}
}
For exposing to QML lists of QObject-derived types, one should use QQmlListProperty rather than QList<T>
as the property type 为了向QML派生QObject派生类型的列表,应该使用QQmlListProperty而不是QList<T>
作为属性类型。
MyClass.h: MyClass.h:
Q_PROPERTY (QQmlListProperty<MySubClass> objectList READ getMySubClassList NOTIFY objectListChanged)
public:
QQmlListProperty<MySubClass> getMySubClassList() {
return QQmlListProperty<MySubClass>(this, 0, &MyClass::countMySubClassList, &MyClass::atMySubClassList);
}
static int countMySubClassList(QQmlListProperty<MySubClass> *property) {
MyClass *m = qobject_cast<MyClass *>(property->object);
return m->m_objectList.size();
}
static MySubClass *atMySubClassList(QQmlListProperty<MySubClass> *property, int index) {
MyClass *m = qobject_cast<MyClass *>(property->object);
return m->m_objectList[index];
}
private:
QList<MySubClass *> m_objectList
Also, you should register MySubClass
type in the QML system, by using qmlRegisterUncreatableType 另外,您应该使用qmlRegisterUncreatableType在QML系统中注册MySubClass
类型。
qmlRegisterUncreatableType<MySubClass,1>("project.mySubClass",1,0,"mySubClass","error message");
尝试在类定义之后添加Q_DECLARE_METATYPE(MySubClass*)
,在我的情况下,QList工作正常,啊,我将QObjectList作为属性传递
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.