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

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

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

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

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

public:
    QQmlListProperty<Person> guests() ;

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

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

private:
    QVector<Person *> m_guests;
};
    从上面的代码中可以看到,BirthdayParty 类中还有许多成员函数,这些函数主要是提供给 QQmlListProperty  回调的,QQmlListProperty  构造函数声明如下:
QQmlListProperty(QObject *object, QList<T *> &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<Person *> m_guests;

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

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

QQmlListProperty<Person> BirthdayParty::guests()
{
    return QQmlListProperty<Person>(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<Person> *list, Person *guest)
{
    reinterpret_cast<BirthdayParty *>(list->data)->appendGuest(guest);
}

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

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

void BirthdayParty::clearGuests(QQmlListProperty<Person> *list)
{
    reinterpret_cast<BirthdayParty *>(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 <QObject>

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 <QObject>
#include <QQmlListProperty>
#include <QVector>

#include "Person.h"

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


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

    Person* host() const;

    QQmlListProperty<Person> 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> *, Person *guest);
    static int guestCount(QQmlListProperty<Person> *);
    static Person *guestAt(QQmlListProperty<Person> *,int idx);
    static void clearGuests(QQmlListProperty<Person> *);

private:
    Person* m_host;

    QVector<Person *> m_guests;
};

#endif // BIRTHDAYPARTY_H


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

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

}

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

QQmlListProperty<Person> BirthdayParty::guests()
{
    return QQmlListProperty<Person>(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<Person> *list, Person *guest)
{
    reinterpret_cast<BirthdayParty *>(list->data)->appendGuest(guest);
}

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

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

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


// main.cpp
#include <QCoreApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>

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

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

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

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

    BirthdayParty *party = qobject_cast<BirthdayParty *>(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"






    

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: QMLC++的交互可以通过Qt的信号槽机制来实现。在QML中声明一个信号,然后在C++中连接信号并且在槽函数中处理数组操作即可。 具体实现流程如下: 1. 在QML中声明一个信号signalToC,用于向C++发送数组。 ``` signal signalToC(variant array) ``` 2. 在C++中定义一个Q_INVOKABLE槽函数,用于接收QVariant类型的数组参数。 ``` Q_INVOKABLE void arraySlot(QVariant array) { QVariantList list = array.toList(); for (int i = 0; i < list.size(); ++i) { int element = list.at(i).toInt(); qDebug() << "element" << i << ":" << element; // 处理数组操作 } } ``` 3. 在C++中连接QML的信号与槽函数。 ``` QObject* rootObject = engine.rootObjects().at(0); QObject* qmlObject = rootObject->findChild<QObject*>("qmlObject"); QObject::connect(qmlObject, SIGNAL(signalToC(QVariant)), qmlObject, SLOT(arraySlot(QVariant))); ``` 4. 在QML中发送数组。 ``` signalToC([1, 2, 3]) ``` 通过以上步骤,就可以实现QMLC++之间的数组交互。在QML中可以将需要处理的数组作为参数发送给C++,然后C++再通过处理槽函数对数组进行处理。同时,在槽函数中也可以将处理结果发送回QML,进行下一步处理。 ### 回答2: QML是一种声明性的语言,通常用于跨平台开发。它可以用于构建用户界面,也可以用于实现业务逻辑,同时还支持各种数据类型的处理,包括数组。而C是一种结构化编程语言,通常适用于系统级编程。C语言中可以使用数组来存储和处理数据。 在QML中使用C语言的方式包括QML调用C函数和C直接访问QML对象。在QML中,使用JS Arrays来表示数组。我们可以在QML中声明一个整形数组,然后将其传递给C代码。C代码可以通过参数列表或者函数调用方式获得数组。 当C处理完数据之后,可以将处理结果传递回QML界面,以更新视图显示。因为QML和C之间的交互需要通过中间层来实现,所以性能方面需要进行一些考虑,以确保交互效率和数据处理效率。比如,可以使用异步回调机制获得更好的响应速度,同时也需要注意内存管理和资源释放。 总之,使用C与QML交互读取数组需要一定的开发经验和编程技巧。需要开发者熟悉QML和C编程语言,并且了解二者之间的差异和交互方式。只有具备了充足的知识和技能,才能够开发出高效、稳定、可靠的跨平台应用程序。 ### 回答3: 在QML中,可以使用JavaScript来实现对C++数组的交互读取。 首先,需要在C++代码中创建一个数组,并将其暴露给QML。可以使用Q_PROPERTY宏定义一个带有读取函数的成员变量,在QML中通过属性绑定来读取该数组。 例如,假设我们有一个名为Data的类,其中有一个整数数组: ``` class Data : public QObject { Q_OBJECT Q_PROPERTY(QVariantList array READ getArray NOTIFY arrayChanged) public: explicit Data(QObject *parent = nullptr); QVariantList getArray() const; Q_INVOKABLE void setArray(const QVariantList& array); signals: void arrayChanged(); private: int m_array[3]; }; ``` 在构造函数中将数组初始化,并将其转换为QVariantList类型,以便在QML中使用。注意,必须使用Q_INVOKABLE标记来声明可以从QML调用的成员函数。 ``` Data::Data(QObject *parent) : QObject(parent) { m_array[0] = 1; m_array[1] = 2; m_array[2] = 3; } QVariantList Data::getArray() const { QVariantList list; for (int i = 0; i < 3; i++) { list.append(m_array[i]); } return list; } void Data::setArray(const QVariantList& array) { for (int i = 0; i < 3; i++) { m_array[i] = array.value(i).toInt(); } emit arrayChanged(); } ``` 在QML中,可以使用该数组属性来读取和修改数组数据。例如,下面的QML代码使用一个ListView来显示数组: ``` import QtQuick 2.0 import MyApp 1.0 ListView { model: myData.array delegate: Text { text: modelData } } ``` 同时,也可以通过QML将新的数组数据写入到C++数组中: ``` import QtQuick 2.0 import MyApp 1.0 Button { text: "Update array" onClicked: { myData.setArray([4, 5, 6]) } } ``` 总之,使用Q_PROPERTY和Q_INVOKABLE可以实现在QML中读取和修改C++数组的功能,提供了很多灵活性和可扩展性。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值