QML入门之 QML访问 C++类中的数组 (三)

    本篇主要介绍 QQmlListProperty 类的使用, 通过 QQmlListProperty  类实现 QML 与 C++ 类的交互。

    本篇以官方示例 properties 为例,重点内容如下:

    首先使用 Q_PROPERTY 注册 guests 属性,guests 是一个数组

class BirthdayParty : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QQmlListProperty guests READ guests)

public:
    QQmlListProperty guests() ;

    void appendGuest(Person *guest);
    int guestCount() const;
    Person *guestAt(int idx) const;
    void clearGuests();

private:
    static void appendGuest(QQmlListProperty *, Person *guest);
    static int guestCount(QQmlListProperty *);
    static Person *guestAt(QQmlListProperty *,int idx);
    static void clearGuests(QQmlListProperty *);

private:
    QVector m_guests;
};
    从上面的代码中可以看到,BirthdayParty 类中还有许多成员函数,这些函数主要是提供给 QQmlListProperty  回调的,QQmlListProperty  构造函数声明如下:
QQmlListProperty(QObject *object, QList &list)    // 1
QQmlListProperty(QObject *object, void *data, AppendFunction append, CountFunction count, AtFunction at, ClearFunction clear) //2
QQmlListProperty(QObject *object, void *data, CountFunction count, AtFunction at) // 3

    第一个构造函数最简单,但由于我们在 BirthdayParty 中声明的是

QVector m_guests;

    如果是 QList类型,我们可以使用第一个构造,在上一篇中我们就使用了第一个构造函数。

    第二个和第三个不同点:第三个是只读的。我们使用的是第二个构造函数,使用方法如下:

QQmlListProperty BirthdayParty::guests()
{
    return QQmlListProperty(this, this,
                                    &BirthdayParty::appendGuest,
                                    &BirthdayParty::guestCount,
                                    &BirthdayParty::guestAt,
                                    &BirthdayParty::clearGuests);
}

void BirthdayParty::setHost(Person *host)
{
    m_host = host;
}

void BirthdayParty::appendGuest(Person *guest)
{
    m_guests.append(guest);
}

int BirthdayParty::guestCount() const
{
    return m_guests.count();
}

Person *BirthdayParty::guestAt(int idx) const
{
    return m_guests.at(idx);
}

void BirthdayParty::clearGuests()
{
    m_guests.clear();
}

void BirthdayParty::appendGuest(QQmlListProperty *list, Person *guest)
{
    reinterpret_cast(list->data)->appendGuest(guest);
}

int BirthdayParty::guestCount(QQmlListProperty *list)
{
    return reinterpret_cast(list->data)->guestCount();
}

Person *BirthdayParty::guestAt(QQmlListProperty *list,int idx)
{
    return reinterpret_cast(list->data)->guestAt(idx);
}

void BirthdayParty::clearGuests(QQmlListProperty *list)
{
    reinterpret_cast(list->data)->clearGuests();
}



完整的程序代码如下:

// pro 文件
QT += core qml

HEADERS += \
    BirthdayParty.h \
    Person.h

SOURCES += \
    BirthdayParty.cpp \
    Person.cpp \
    main.cpp

RESOURCES += \
    resource.qrc 


// Person.h
#ifndef PERSON_H
#define PERSON_H

#include 

class Person : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName)
    Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
public:
    explicit Person(QObject *parent = nullptr);

    QString name() const;

    int shoeSize() const;

signals:

public slots:

    void setName(QString name);

    void setShoeSize(int shoeSize);

private:

    QString m_name;
    int m_shoeSize;
};

#endif // PERSON_H

// Person.cpp
#include "Person.h"

Person::Person(QObject *parent) : QObject(parent)
{

}

QString Person::name() const
{
    return m_name;
}

int Person::shoeSize() const
{
    return m_shoeSize;
}

void Person::setName(QString name)
{
    m_name = name;
}

void Person::setShoeSize(int shoeSize)
{
    m_shoeSize = shoeSize;
}

// Birthday.h
#ifndef BIRTHDAYPARTY_H
#define BIRTHDAYPARTY_H

#include 
#include 
#include 

#include "Person.h"

class BirthdayParty : public QObject
{
    Q_OBJECT
    Q_PROPERTY(Person* host READ host WRITE setHost)
    Q_PROPERTY(QQmlListProperty guests READ guests)


public:
    explicit BirthdayParty(QObject *parent = nullptr);

    Person* host() const;

    QQmlListProperty guests() ;
    void appendGuest(Person *guest);
    int guestCount() const;
    Person *guestAt(int idx) const;
    void clearGuests();

signals:

public slots:
    void setHost(Person* host);

private:
    static void appendGuest(QQmlListProperty *, Person *guest);
    static int guestCount(QQmlListProperty *);
    static Person *guestAt(QQmlListProperty *,int idx);
    static void clearGuests(QQmlListProperty *);

private:
    Person* m_host;

    QVector m_guests;
};

#endif // BIRTHDAYPARTY_H


// BirthdayParty.cpp
#include "BirthdayParty.h"

BirthdayParty::BirthdayParty(QObject *parent) : QObject(parent)
{

}

Person *BirthdayParty::host() const
{
    return m_host;
}

QQmlListProperty BirthdayParty::guests()
{
    return QQmlListProperty(this, this,
                                    &BirthdayParty::appendGuest,
                                    &BirthdayParty::guestCount,
                                    &BirthdayParty::guestAt,
                                    &BirthdayParty::clearGuests);
}

void BirthdayParty::setHost(Person *host)
{
    m_host = host;
}

void BirthdayParty::appendGuest(Person *guest)
{
    m_guests.append(guest);
}

int BirthdayParty::guestCount() const
{
    return m_guests.count();
}

Person *BirthdayParty::guestAt(int idx) const
{
    return m_guests.at(idx);
}

void BirthdayParty::clearGuests()
{
    m_guests.clear();
}

void BirthdayParty::appendGuest(QQmlListProperty *list, Person *guest)
{
    reinterpret_cast(list->data)->appendGuest(guest);
}

int BirthdayParty::guestCount(QQmlListProperty *list)
{
    return reinterpret_cast(list->data)->guestCount();
}

Person *BirthdayParty::guestAt(QQmlListProperty *list,int idx)
{
    return reinterpret_cast(list->data)->guestAt(idx);
}

void BirthdayParty::clearGuests(QQmlListProperty *list)
{
    reinterpret_cast(list->data)->clearGuests();
}


// main.cpp
#include 
#include 
#include 
#include 

#include "Person.h"
#include "BirthdayParty.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qmlRegisterType("People", 1, 0, "BirthdayParty");
    qmlRegisterType("People", 1, 0, "Person");

    QQmlEngine engine;
    QQmlComponent component(&engine, QUrl("qrc:example.qml"));

    BirthdayParty *party = qobject_cast(component.create());

    if(party && party->host())
    {
        qDebug() << party->host()->name() << "has a birthday party";
        qDebug() << "he is inviting:";

        for(int i = 0; i < party->guestCount(); i++)
        {
            qDebug()<< "\t" << party->guestAt(i)->name();
        }
    }
    else
    {
        qCritical() << component.errorString();
    }

    return 0;
}


// example.qml
import People 1.0

// ![0]
BirthdayParty {
    host: Person {
        name: "Bob Jones"
        shoeSize: 12
    }
    guests: [
        Person { name: "Leo Hodges" },
        Person { name: "Jack Smith" },
        Person { name: "Anne Brown" }
    ]
}

程序运行结果:

"Bob Jones" has a birthday party
he is inviting:
	 "Leo Hodges"
	 "Jack Smith"
	 "Anne Brown"






    

你可能感兴趣的:(QML,QML,Qt,C++)