1. 程式人生 > >QML入門之QML呼叫C++類中方法(二)

QML入門之QML呼叫C++類中方法(二)

本篇以 Qt 官方示例 methods 介紹 QML 呼叫 C++ 類中的方法。

核心就是在 C++ 類中使用 巨集 Q_INVOKABLE 宣告方法

class BirthdayParty : public QObject
{
    Q_OBJECT
    // ...
    Q_INVOKABLE void invite(const QString &name);
}

然後就可以在 qml 中呼叫該方法

BirthdayParty {
    // ...
    Component.onCompleted: invite("劉楊")
}
// methods.pro
QT = core qml

SOURCES += main.cpp \
           person.cpp \
           birthdayparty.cpp
HEADERS += person.h \
           birthdayparty.h
RESOURCES += methods.qrc

target.path = $$[QT_INSTALL_EXAMPLES]/qml/referenceexamples/methods
INSTALLS += target
// 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:
    Person(QObject *parent = 0);

    QString name() const;
    void setName(const QString &);

    int shoeSize() const;
    void setShoeSize(int);
private:
    QString m_name;
    int m_shoeSize;
};

#endif // PERSON_H
// Person.cpp
#include "person.h"

Person::Person(QObject *parent)
: QObject(parent), m_shoeSize(0)
{
}

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

void Person::setName(const QString &n)
{
    m_name = n;
}

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

void Person::setShoeSize(int s)
{
    m_shoeSize = s;
}
// BirthdayParty.h
#ifndef BIRTHDAYPARTY_H
#define BIRTHDAYPARTY_H

#include <QObject>
#include <QQmlListProperty>
#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:
    BirthdayParty(QObject *parent = 0);

    Person *host() const;
    void setHost(Person *);

    QQmlListProperty<Person> guests();
    int guestCount() const;
    Person *guest(int) const;

    Q_INVOKABLE void invite(const QString &name);

private:
    Person *m_host;
    QList<Person *> m_guests;
};

#endif // BIRTHDAYPARTY_H
// BirthdayParty.cpp
#include "birthdayparty.h"

BirthdayParty::BirthdayParty(QObject *parent)
: QObject(parent), m_host(0)
{
}

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

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

QQmlListProperty<Person> BirthdayParty::guests()
{
    return QQmlListProperty<Person>(this, m_guests);
}

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

Person *BirthdayParty::guest(int)
{

}

Person *BirthdayParty::guest(int index) const
{
    return m_guests.at(index);
}

void BirthdayParty::invite(const QString &name)
{
    Person *person = new Person(this);
    person->setName(name);
    m_guests.append(person);
}
// main.cpp
#include <QCoreApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>
#include "birthdayparty.h"
#include "person.h"

int main(int argc, char ** argv)
{
    QCoreApplication app(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()) {
        qWarning() << party->host()->name() << "is having a birthday!";
        qWarning() << "They are inviting:";
        for (int ii = 0; ii < party->guestCount(); ++ii)
            qWarning() << "   " << party->guest(ii)->name();
    } else {
        qWarning() << component.errors();
    }

    return 0;
}
// example.qml
import QtQuick 2.0
import People 1.0

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

    Component.onCompleted: invite("William Green")
}

執行結果如下:

"Bob Jones" is having a birthday!
They are inviting:
    "Leo Hodges"
    "Jack Smith"
    "Anne Brown"
    "William Green"