• Qt5官方demo解析集28——Extending QML


    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873

    接上文Qt5官方demo解析集27——Extending QML - Attached Properties Example


    这个demo演示了为QML自己定义类型加入信号的方法。这与Qt5官方demo解析集16——Chapter 2: Connecting to C++ Methods and Signals所介绍的差点儿相同。鉴于样例的尺寸,可能那一篇要更清晰一些。


    不管怎样,我们还是要继续扩展这个BirthdayParty例程。我们为这个生日派对加入了一个“派对開始”的信号,并定义了一个函数用来发射这个信号。


    因为person类依旧没有改变。我们看看小小修改了的birthdayparty.h:

    #ifndef BIRTHDAYPARTY_H
    #define BIRTHDAYPARTY_H
    
    #include <QObject>
    #include <QDate>
    #include <qqml.h>
    #include "person.h"
    
    class BirthdayPartyAttached : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QDate rsvp READ rsvp WRITE setRsvp)
    public:
        BirthdayPartyAttached(QObject *object);
    
        QDate rsvp() const;
        void setRsvp(const QDate &);
    
    private:
        QDate m_rsvp;
    };
    
    class BirthdayParty : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(Person *host READ host WRITE setHost)
        Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
        Q_CLASSINFO("DefaultProperty", "guests")
    public:
        BirthdayParty(QObject *parent = 0);
    
        Person *host() const;
        void setHost(Person *);
    
        QQmlListProperty<Person> guests();
        int guestCount() const;
        Person *guest(int) const;
    
        static BirthdayPartyAttached *qmlAttachedProperties(QObject *);
    
        void startParty();                       // 自己定义函数,之所以不使用Q_INVOKABLE是由于该函数是在main.cpp而不是QML中被调用的
    // ![0]
    signals:
        void partyStarted(const QTime &time);   // 自己定义信号
    // ![0]
    
    private:
        Person *m_host;
        QList<Person *> m_guests;
    };
    QML_DECLARE_TYPEINFO(BirthdayParty, QML_HAS_ATTACHED_PROPERTIES)
    
    #endif // BIRTHDAYPARTY_H


    birthdayParty.cpp:

    #include "birthdayparty.h"
    
    BirthdayPartyAttached::BirthdayPartyAttached(QObject *object)
    : QObject(object)
    {
    }
    
    QDate BirthdayPartyAttached::rsvp() const
    {
        return m_rsvp;
    }
    
    void BirthdayPartyAttached::setRsvp(const QDate &d)
    {
        m_rsvp = d;
    }
    
    
    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 index) const
    {
        return m_guests.at(index);
    }
    
    void BirthdayParty::startParty()        // 该函数用来将当前时间作为信号參数发射出去
    {
        QTime time = QTime::currentTime();
        emit partyStarted(time);
    }
    
    BirthdayPartyAttached *BirthdayParty::qmlAttachedProperties(QObject *object)
    {
        return new BirthdayPartyAttached(object);
    }

    example.qml:

    import People 1.0
    import QtQuick 2.0  // For QColor
    
    BirthdayParty {
    // ![0]
        onPartyStarted: console.log("This party started rockin' at " + time); // 在QML中我们不须要额外对信号进行处理
    // ![0]                                                                   // 仅仅须要关注与该信号相应的onXXX函数
                                                                              // 当信号发出时该函数即被运行
        host: Boy {
            name: "Bob Jones"
            shoe { size: 12; color: "white"; brand: "Nike"; price: 90.0 }
        }
    
        Boy {
            name: "Leo Hodges"
            BirthdayParty.rsvp: "2009-07-06"
            shoe { size: 10; color: "black"; brand: "Reebok"; price: 59.95 }
        }
        Boy {
            name: "Jack Smith"
            shoe { size: 8; color: "blue"; brand: "Puma"; price: 19.95 }
        }
        Girl {
            name: "Anne Brown"
            BirthdayParty.rsvp: "2009-07-01"
            shoe.size: 7
            shoe.color: "red"
            shoe.brand: "Marc Jacobs"
            shoe.price: 699.99
        }
    // ![1]
    }
    // ![1]

    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<BirthdayPartyAttached>();
        qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty");
        qmlRegisterType<ShoeDescription>();
        qmlRegisterType<Person>();
        qmlRegisterType<Boy>("People", 1,0, "Boy");
        qmlRegisterType<Girl>("People", 1,0, "Girl");
    
        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!";
    
            if (qobject_cast<Boy *>(party->host()))
                qWarning() << "He is inviting:";
            else
                qWarning() << "She is inviting:";
    
            for (int ii = 0; ii < party->guestCount(); ++ii) {
                Person *guest = party->guest(ii);
    
                QDate rsvpDate;
                QObject *attached = 
                    qmlAttachedPropertiesObject<BirthdayParty>(guest, false);
                if (attached)
                    rsvpDate = attached->property("rsvp").toDate();
    
                if (rsvpDate.isNull())
                    qWarning() << "   " << guest->name() << "RSVP date: Hasn't RSVP'd";
                else
                    qWarning() << "   " << guest->name() << "RSVP date:" << qPrintable(rsvpDate.toString()); // 上文讨论了qPrintable的问题
            }
    
            party->startParty();                       // 这里调用了发射信号函数,因此party開始时间将被打印在最后一行
        } else {
            qWarning() << component.errors();
        }
    
        return 0;
    }

    结果如图:


  • 相关阅读:
    mysql 重置root 账户密码
    Applicationpoolidentity 好有趣哦
    类模板的困扰 LNK2019 (转)
    C++中定义比较函数的三种方法
    Spring的AOP,Struts2的拦截器(Interceptor),以及springMVC的(interceptor)
    MyBatis与Hibernate总结篇
    Java中的回调
    闲来重写一下快速排序
    【lucene】一个简单的招聘网站的建立
    【Lucene】小谈lucene的BooleanQuery查询对象
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7090516.html
Copyright © 2020-2023  润新知