<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                本系列所有文章可以在這里查看[http://blog.csdn.net/cloud_castle/article/category/2123873](http://blog.csdn.net/cloud_castle/article/category/2123873) 接上文[Qt5官方demo解析集29——Extending QML - Property Value Source Example](http://blog.csdn.net/cloud_castle/article/details/37526169) 還記得我們曾經在[Qt5官方demo解析集17——Chapter 3: Adding Property Bindings](http://blog.csdn.net/cloud_castle/article/details/36886779)一文中接觸過QML自定義類型的屬性綁定嗎?如果不記得了,可以移步進行了解。因為項目尺寸的原因,那個例子可能更好理解。 這個例子也是我們Extending QML(擴展QML)系列的最后一個例子了,雖然相較前一個例子也只有小小的改動,不過我們還是把整個工程都完整的看一遍吧~ ![](https://box.kancloud.cn/2016-01-18_569cbd09034fd.jpg) binding.qrc中是我們的qml文件,它實例化了BirthdayParty類以及其所有的子對象。 Person類建立了一個自定義的QML類型,由于它并不是一個可視化組件,且QML任何組件均基于Qt 的元對象系統,因此繼承自QObject。 接著定義了ShoeDescription用來對Person類的shoe屬性進行描述,使用特定的方法,我們在對shoe賦值時不需要實例化這個ShoeDescription組件。 再定義兩個Person的派生類Boy、Girl,可以用來對Person對象分類。 person.h: ~~~ #ifndef PERSON_H #define PERSON_H #include <QObject> #include <QColor> class ShoeDescription : public QObject { Q_OBJECT Q_PROPERTY(int size READ size WRITE setSize NOTIFY shoeChanged) // NOTIFY用在屬性綁定,當該屬性值發生改變時發出信號shoeChanged Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY shoeChanged) // 通過該信號,我們就能使得被綁定的屬性值隨之發生改變 Q_PROPERTY(QString brand READ brand WRITE setBrand NOTIFY shoeChanged) Q_PROPERTY(qreal price READ price WRITE setPrice NOTIFY shoeChanged) public: ShoeDescription(QObject *parent = 0); int size() const; void setSize(int); QColor color() const; void setColor(const QColor &); QString brand() const; void setBrand(const QString &); qreal price() const; void setPrice(qreal); signals: void shoeChanged(); // 定義該shoeChanged()信號 private: int m_size; QColor m_color; QString m_brand; qreal m_price; }; class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) // ![0] Q_PROPERTY(ShoeDescription *shoe READ shoe CONSTANT) // ![0] public: Person(QObject *parent = 0); QString name() const; void setName(const QString &); ShoeDescription *shoe(); signals: void nameChanged(); private: QString m_name; ShoeDescription m_shoe; }; class Boy : public Person { Q_OBJECT public: Boy(QObject * parent = 0); }; class Girl : public Person { Q_OBJECT public: Girl(QObject * parent = 0); }; #endif // PERSON_H ~~~ person.cpp: ~~~ #include "person.h" ShoeDescription::ShoeDescription(QObject *parent) : QObject(parent), m_size(0), m_price(0) { } int ShoeDescription::size() const { return m_size; } void ShoeDescription::setSize(int s) { if (m_size == s) return; m_size = s; emit shoeChanged(); // 該信號應該在該屬性被正確寫入后發出 } QColor ShoeDescription::color() const { return m_color; } void ShoeDescription::setColor(const QColor &c) { if (m_color == c) return; m_color = c; emit shoeChanged(); } QString ShoeDescription::brand() const { return m_brand; } void ShoeDescription::setBrand(const QString &b) { if (m_brand == b) return; m_brand = b; emit shoeChanged(); } qreal ShoeDescription::price() const { return m_price; } void ShoeDescription::setPrice(qreal p) { if (m_price == p) return; m_price = p; emit shoeChanged(); } Person::Person(QObject *parent) : QObject(parent) { } QString Person::name() const { return m_name; } void Person::setName(const QString &n) { if (m_name == n) return; m_name = n; emit nameChanged(); } ShoeDescription *Person::shoe() { return &m_shoe; } Boy::Boy(QObject * parent) : Person(parent) { } Girl::Girl(QObject * parent) : Person(parent) { } ~~~ 接下來是我們的主類BirthdayParty,它也是example.qml中的根項目。它有一個以Person指針為參數的host屬性,用來指明壽星;有一個以Person列表指針為參數guests屬性,用來指明客人,并且該屬性被設置為默認屬性,這樣在QML中沒有指明屬性的值將被劃歸它的名下;一個announcement屬性,用來被動態改變以播放歌詞。另外,該類還定義了一個partyStarted()信號,我們可以在QML中使用onPartyStarted 來響應該信號。 此外,再定義一個BirthdayPartyAttached類,它用來為BirthdayParty提供一個附加屬性。 birthdayparty.h: ~~~ #ifndef BIRTHDAYPARTY_H #define BIRTHDAYPARTY_H #include <QObject> #include <QDate> #include <QDebug> #include <qqml.h> #include "person.h" class BirthdayPartyAttached : public QObject { Q_OBJECT Q_PROPERTY(QDate rsvp READ rsvp WRITE setRsvp NOTIFY rsvpChanged) // 該例中大多數屬性均定義了屬性綁定 public: BirthdayPartyAttached(QObject *object); QDate rsvp() const; void setRsvp(const QDate &); signals: void rsvpChanged(); private: QDate m_rsvp; }; class BirthdayParty : public QObject { Q_OBJECT // ![0] Q_PROPERTY(Person *host READ host WRITE setHost NOTIFY hostChanged) // ![0] Q_PROPERTY(QQmlListProperty<Person> guests READ guests) Q_PROPERTY(QString announcement READ announcement WRITE setAnnouncement) 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; QString announcement() const; void setAnnouncement(const QString &); static BirthdayPartyAttached *qmlAttachedProperties(QObject *); void startParty(); signals: void partyStarted(const QTime &time); void hostChanged(); 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) { if (d != m_rsvp) { m_rsvp = d; emit rsvpChanged(); } } BirthdayParty::BirthdayParty(QObject *parent) : QObject(parent), m_host(0) { } Person *BirthdayParty::host() const { return m_host; } void BirthdayParty::setHost(Person *c) { if (c == m_host) return; m_host = c; emit hostChanged(); } 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); } QString BirthdayParty::announcement() const { return QString(); } void BirthdayParty::setAnnouncement(const QString &speak) { qWarning() << qPrintable(speak); } BirthdayPartyAttached *BirthdayParty::qmlAttachedProperties(QObject *object) { return new BirthdayPartyAttached(object); } ~~~ 在該系列第9個例子中,我們接觸到了HappyBirthdaySong類,它是一個自定義的Property Value Source,用來為QML屬性提供隨時間變化的能力,類似于Animation。在該例子中,它被用于announcement屬性。 happybirthdaysong.h: ~~~ #ifndef HAPPYBIRTHDAYSONG_H #define HAPPYBIRTHDAYSONG_H #include <QQmlPropertyValueSource> #include <QQmlProperty> #include <QStringList> class HappyBirthdaySong : public QObject, public QQmlPropertyValueSource { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_INTERFACES(QQmlPropertyValueSource) public: HappyBirthdaySong(QObject *parent = 0); virtual void setTarget(const QQmlProperty &); QString name() const; void setName(const QString &); private slots: void advance(); signals: void nameChanged(); private: int m_line; QStringList m_lyrics; QQmlProperty m_target; QString m_name; }; #endif // HAPPYBIRTHDAYSONG_H ~~~ happybirthdaysong.cpp: ~~~ #include "happybirthdaysong.h" #include <QTimer> HappyBirthdaySong::HappyBirthdaySong(QObject *parent) : QObject(parent), m_line(-1) { setName(QString()); QTimer *timer = new QTimer(this); QObject::connect(timer, SIGNAL(timeout()), this, SLOT(advance())); timer->start(1000); } void HappyBirthdaySong::setTarget(const QQmlProperty &p) { m_target = p; } QString HappyBirthdaySong::name() const { return m_name; } void HappyBirthdaySong::setName(const QString &name) { if (m_name == name) return; m_name = name; m_lyrics.clear(); m_lyrics << "Happy birthday to you,"; m_lyrics << "Happy birthday to you,"; m_lyrics << "Happy birthday dear " + m_name + ","; m_lyrics << "Happy birthday to you!"; m_lyrics << ""; emit nameChanged(); } void HappyBirthdaySong::advance() { m_line = (m_line + 1) % m_lyrics.count(); m_target.write(m_lyrics.at(m_line)); } ~~~ 在main.cpp中將這些C++類注冊成QML類型后,我們就可以在QML中創建一個實例化的BirthdayParty,并對其屬性賦值: example.qml: ~~~ import People 1.0 import QtQuick 2.0 // For QColor // ![0] BirthdayParty { id: theParty HappyBirthdaySong on announcement { name: theParty.host.name } // 屬性綁定 host: Boy { name: "Bob Jones" shoe { size: 12; color: "white"; brand: "Nike"; price: 90.0 } } // ![0] onPartyStarted: console.log("This party started rockin' at " + time); 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 "happybirthdaysong.h" #include "person.h" int main(int argc, char ** argv) { QCoreApplication app(argc, argv); qmlRegisterType<BirthdayPartyAttached>(); qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty"); qmlRegisterType<HappyBirthdaySong>("People", 1,0, "HappyBirthdaySong"); 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()); } party->startParty(); } else { qWarning() << component.errors(); } return app.exec(); } ~~~ 輸出如下: ![](https://box.kancloud.cn/2016-01-18_569cbd0917427.jpg)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看