Running into issues with QVariantLists and QLists of custom QObjects

◇◆丶佛笑我妖孽 提交于 2019-12-25 03:37:25

问题


I'm hoping to get some help with a snag I've run into on a personal project. Essentially I have a custom QObject inheritor that contains its own various elements of data, and another custom QObject that I would like to have some collection element of multiple instances of the other custom QObject. I've tried various ways of implementing this and thus far I've had no real success, the closest being with a QVariantList. The following snippets are from an example I wrote to recreate the issue, but they follow the same general structure as their more detailed counterparts.

Data represents the initial custom QObject.

"data.h"

#ifndef DATA_H
#define DATA_H
#include <QObject>

class Data : public QObject
{
    Q_OBJECT
public:
explicit Data(QObject *parent = 0);
Data(const Data &other);
~Data();
QString getName();
QString getContent();
void setName(QString newName);
void setContent(QString newContent);

private:
QString name, content;
};

Q_DECLARE_METATYPE(Data)

#endif // DATA_H

"data.cpp"

#include "data.h"

Data::Data(QObject *parent) :
QObject(parent)
{
name = "testData";
content = "testContent";
}

Data::Data(const Data &other){}

Data::~Data(){}

QString Data::getName(){return name;}

QString Data::getContent(){return content;}

void Data::setName(QString newName){name = newName;}

void Data::setContent(QString newContent){content = newContent;}

TestContainer is the object which will hold some collection of Data

"testcontainer.h"

#ifndef TESTCONTAINTER_H
#define TESTCONTAINER_H

#include <QObject>
#include <QString>
#include <QVariantList>
#include "data.h"

class TestContainer : public QObject
{
Q_OBJECT
public:
explicit TestContainer(QObject *parent = 0);
TestContainer(const TestContainer &other);
Q_INVOKABLE QVariantList getList();

private:
QString name;
QVariantList theList;

};

Q_DECLARE_METATYPE(TestContainer)

#endif // TESTCONTAINTER_H

"testcontainer.cpp"

#include "testcontainer.h"

TestContainer::TestContainer(QObject *parent) :
QObject(parent)
{
name = "test container";
Data temp;
theList.append(QVariant::fromValue(temp));
}

TestContainer::TestContainer(const TestContainer &other){
name = other.name;
theList = other.theList;
}

QVariantList TestContainer::getList(){return theList;}

"main.cpp"

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "testcontainer.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

qRegisterMetaType<TestContainer>("TestContainer");

QQmlApplicationEngine engine;

TestContainer theContainer;
engine.rootContext()->setContextProperty("theContainer", &theContainer);

engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

return app.exec();
}

"main.qml"

import QtQuick 2.3
import QtQuick.Controls 1.2

ApplicationWindow {
visible: true
width: 320
height: 240
title: qsTr("Testing Functionality")

Text {
    text: theContainer.getList()[0].getName();
    anchors.centerIn: parent
}
}

Put together all of this provides me with a nice:

"TypeError: Property 'getName' of object QVariant(Data) is not a function"

Thoughts?


回答1:


After hours of research and more trial and error I've finally discovered a solution that works for me. Rather than trying to force a QList<Object*> or QVariantList to function correctly I managed to get everything working with QList<Data*> and QQmlListProperty<Data>. Currently I am able to both use the QList as a model for things like TableView and am also able to access individual elements of the list. For models it goes something like:

model: testContainer.theList

And to access an individual element something like:

text: theContainer.getData(0).name

The following is the current code that achieves this:

"data.h"

#ifndef DATA_H
#define DATA_H

#include <QObject>

class Data : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ getName WRITE setName)
    Q_PROPERTY(QString content READ getContent WRITE setContent)
public:
    explicit Data(QObject *parent = 0);
    QString getName();
    QString getContent();
    void setName(QString newName);
    void setContent(QString newContent);

private:
    QString name, content;
};

#endif // DATA_H

"data.cpp"

#include "data.h"

Data::Data(QObject *parent) :
    QObject(parent){}

QString Data::getName(){return name;}

QString Data::getContent(){return content;}

void Data::setName(QString newName){name = newName;}

void Data::setContent(QString newContent){content = newContent;}

"testContainer.h"

#ifndef TESTCONTAINTER_H
#define TESTCONTAINER_H

#include <QObject>
#include <QList>
#include <QQmlListProperty>

#include "data.h"

class TestContainer : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QQmlListProperty<Data> theList READ getList)
public:
    explicit TestContainer(QObject *parent = 0);
    QQmlListProperty<Data> getList();
    void addData(Data* d);
    Q_INVOKABLE Data* getData(int i);

private:
    QString name;
    QList<Data*> theList;
};

#endif // TESTCONTAINTER_H

"testContainer.cpp"

#include "testcontainer.h"

TestContainer::TestContainer(QObject *parent) :
    QObject(parent){}

QQmlListProperty<Data> TestContainer::getList(){
    return QQmlListProperty<Data>(this, theList);}

void TestContainer::addData(Data* d){theList.append(d);}

Data* TestContainer::getData(int i){return theList.at(i);}

"main.cpp"

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTQml>

#include "testcontainer.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    qmlRegisterType<Data>("Custom", 1, 0, "Data");
    qmlRegisterType<TestContainer>("Custom", 1, 0, "TestContainer");

    QQmlApplicationEngine engine;

    TestContainer theContainer;
    Data d1;
    d1.setName("test name 1");
    d1.setContent("test content 1");
    Data d2;
    d2.setName("test name 2");
    d2.setContent("test content 2");
    theContainer.addData(&d1);
    theContainer.addData(&d2);
    engine.rootContext()->setContextProperty("theContainer", &theContainer);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}


来源:https://stackoverflow.com/questions/26398932/running-into-issues-with-qvariantlists-and-qlists-of-custom-qobjects

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!