本系列全部文章能够在这里查看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;
}

结果如图:

Qt5官方demo解析集28——Extending QML - Signal Support Example的更多相关文章

  1. Qt5官方demo解析集30——Extending QML - Binding Example

    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集29--Extendin ...

  2. Qt5官方demo解析集21——Extending QML - Adding Types Example

    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 又是一个新的系列了,只是这个系列和我们之前的Chapt ...

  3. Qt5官方demo分析集29——Extending QML - Property Value Source Example

    此系列的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集28--Extend ...

  4. Qt5官方demo解析集13——Qt Quick Particles Examples - Image Particles

    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文 Qt5官方demo解析集12--Qt Quic ...

  5. Qt5官方demo解析集35——Music Player(使用winextras模块)

    本系列所有文章可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集34——Concentr ...

  6. Qt5官方demo解析集(36个)

    http://blog.csdn.net/cloud_castle/article/category/2123873 http://blog.csdn.net/cloud_castle/article ...

  7. Qt5官方demo分析集11——Qt Quick Particles Examples - Affectors

    在这个系列中的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集10--Qt ...

  8. Qt5官方demo分析集10——Qt Quick Particles Examples - Emitters

    此系列的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 前段时间去听了Qt在北京的开发人员大会,感觉QML ...

  9. Dubbo系列(3)_官方Demo说明

    一.本文目的     通过Dubbo的官方Demo介绍,学会搭建一个简单的Dubbo程序,包括服务端.客户端.接口等. Demo地址:https://github.com/alibaba/dubbo/ ...

随机推荐

  1. springboot 前后端分离开发解决跨域访问

    最近新学习了Java EE开发框架springboot,我在使用springboot前后台分离开发的过程中遇到了跨域求问题.在网上寻找答案的过程中发现网上的解决方案大多比较零散,我在这里整理一个解决方 ...

  2. 【iOS开发-88】事件传递原理解释哪个控件处理事件以及响应者链条的介绍

    一.触摸事件传递原理 (1)大的方向是:从父控件传递给子控件. --父控件会先检查自己能否接受事件的处理 --然后再看看触摸在不在自己的范围内 --假设在的话,就遍历子控件.看看有没有合适的子控件能够 ...

  3. 【基础篇】点击Button按钮更换图片

    我们在开发的过程中,往往为了美化界面的需要,会修改按钮的默认外观,而因为Android中的按钮有三种状态—默认,被点击,被选中.所以,如果要改变按钮的外观,需要对这三种情况都做出修改,也许在以往,我们 ...

  4. AIX查看HBA卡的WWN号

    1,获得AIX主机连接的光纤设备:        # lsdev -Cc adapter -S a | grep fcs         fcs0      Available 09-08 FC Ad ...

  5. 小米开源文件管理器MiCodeFileExplorer-源码研究(2)-2个单实例工具类

    从本篇开始,讲解net.micode.fileexplorer.util工具包中的类.这个包下的类,功能也比较单一和独立.很多代码的思想和实现,可以用于JavaWeb和Android等多种环境中. 一 ...

  6. Myeclipse学习总结(2)——MyEclipse快捷键大全

    1.ctrl+shift+R 打开资源 此组快捷键可以打开工程中任意一个文件,而本人只需按文件名或者mask名的字母顺序输入就会出现对应的文件或者在内容中某个关键字再按快捷键也可以的,例如:Custo ...

  7. Android学习笔记进阶20之得到图片的缩略图

    <1>简介 之前往往是通过Bitmap.Drawable和Canvas配合完成,需要写一系列繁杂的逻辑去缩小原有图片,从而得到缩略图. 现在我给大家介绍一种比较简单的方法:(网上有) 在A ...

  8. 嵌入式 Linux应用程序如何读取(修改)芯片寄存器的值

    这一问题来自项目中一个实际的需求:我需要在Linux启动之后,确认我指定的芯片寄存器是否与我在uboot的配置一致. 举个例子:寄存器地址:0x20000010负责对DDR2的时序配置,该寄存器是在u ...

  9. call、apply、bind 区别

    1.为什么要用 call .apply? 为了 改变方法里面的属性而不去改变原来的方法 function fruits() {} fruits.prototype = { color: "r ...

  10. 【Codeforces Round #428 (Div. 2) C】Journey

    [Link]:http://codeforces.com/contest/839/problem/C [Description] 给一棵树,每当你到一个点x的时候,你进入x的另外一每一个出度的概率都是 ...