界面:

ButterflyGraph:

可以看出,本工程在主程序main里调用窗口界面qmywidget,窗口界面继承了QWidget,并调用自定义类qperson,推测是qmywidget类中的一个属性

qmywidget的实现,调用了显示界面ui_qmywidget,包含了元对象QMetaProperty

UML图:

QmyWidget中,on开头的都是槽函数,QmyWidget是主窗口,所以不发射信号,只接收信号

main.cpp

 1 #include "qmywidget.h"
2 #include <QApplication>
3
4 int main(int argc, char *argv[])
5 {
6 QApplication a(argc, argv);
7 QmyWidget w;
8 w.show();
9
10 return a.exec();
11 }

qperson.h

 1 #ifndef QPERSON_H
2 #define QPERSON_H
3
4 #include <QObject>
5
6 class QPerson : public QObject
7 {
8 Q_OBJECT
9
10 Q_CLASSINFO("author","Wang")
11 Q_CLASSINFO("company","UPC")
12 Q_CLASSINFO("version","1.0.0")
13
14 Q_PROPERTY(int age READ age WRITE setAge NOTIFY ageChanged)
15 Q_PROPERTY(QString name MEMBER m_name)
16 Q_PROPERTY(int score MEMBER m_score)
17 private:
18 int m_age=10;
19 QString m_name;
20 int m_score=79;
21 public:
22 explicit QPerson(QString fName, QObject *parent = nullptr);
23
24 int age();
25 void setAge(int value);
26
27 void incAge();
28 signals:
29 void ageChanged( int value);
30
31 public slots:
32 };
33
34 #endif // QPERSON_H

qmywidget.cpp

  1 #include "qmywidget.h"
2 #include "ui_qmywidget.h"
3 #include <QMetaProperty>
4
5 QmyWidget::QmyWidget(QWidget *parent) :
6 QWidget(parent),
7 ui(new Ui::QmyWidget)
8 {//构造函数
9 ui->setupUi(this);
10
11 boy=new QPerson("王小明");
12 boy->setProperty("score",95);
13 boy->setProperty("age",10);
14 boy->setProperty("sex","Boy");//动态属性
15 // connect(boy,SIGNAL(ageChanged(int)),this,SLOT(on_ageChanged(int)));
16 connect(boy,&QPerson::ageChanged,this,&QmyWidget::on_ageChanged);
17
18 girl=new QPerson("张小丽");
19 girl->setProperty("score",81);
20 girl->setProperty("age",20);
21 girl->setProperty("sex","Girl");//动态属性
22 connect(girl,&QPerson::ageChanged,this,&QmyWidget::on_ageChanged);
23
24 ui->spinBoy->setProperty("isBoy",true); //动态属性
25 ui->spinGirl->setProperty("isBoy",false);
26
27 // 不能使用此形式,因为QSpinBox有两种参数形式的valueChanged()信号
28 // connect(ui->spinGirl,&QSpinBox::valueChanged,
29 // this,&QmyWidget::on_spinBoy_valueChanged);
30 connect(ui->spinGirl,SIGNAL(valueChanged(int)),
31 this,SLOT(on_spin_valueChanged(int)));
32 connect(ui->spinBoy,SIGNAL(valueChanged(int)),
33 this,SLOT(on_spin_valueChanged(int)));
34 }
35
36 QmyWidget::~QmyWidget()
37 {
38 delete ui;
39 }
40
41 void QmyWidget::on_ageChanged( int value)
42 {//响应QPerson的ageChanged()信号
43 Q_UNUSED(value);
44 QPerson *aPerson = qobject_cast<QPerson *>(sender()); //类型投射
45 QString hisName=aPerson->property("name").toString(); //姓名
46 // QString hisName=aPerson->name(); //获取姓名,错误
47 QString hisSex=aPerson->property("sex").toString(); //动态属性
48 int hisAge=aPerson->age();//通过接口函数获取年龄
49 // int hisAge=aPerson->property("age").toInt();//通过属性获得年龄
50
51 ui->textEdit->appendPlainText(hisName+","+hisSex
52 +QString::asprintf(",年龄=%d",hisAge));
53 }
54
55 void QmyWidget::on_btnClear_clicked()
56 {//"清空文本框"按钮
57 ui->textEdit->clear();
58 }
59
60 void QmyWidget::on_btnBoyInc_clicked()
61 {//"boy长大一岁"按钮
62 boy->incAge();
63 }
64
65 void QmyWidget::on_btnGirlInc_clicked()
66 {//"girl长大一岁"按钮
67 girl->incAge();
68 }
69
70 void QmyWidget::on_spin_valueChanged(int arg1)
71 {//响应界面上spinBox的valueChanged(int)信号
72 Q_UNUSED(arg1);
73 QSpinBox *spinBox = qobject_cast<QSpinBox *>(sender());
74 if (spinBox->property("isBoy").toBool())
75 boy->setAge(spinBox->value());
76 else
77 girl->setAge(spinBox->value());
78 }
79
80 void QmyWidget::on_btnClassInfo_clicked()
81 {//"类的元对象信息"按钮
82 const QMetaObject *meta=boy->metaObject();
83 // const QMetaObject *meta=girl->metaObject();
84 // const QMetaObject *meta=ui->spinBoy->metaObject();
85 ui->textEdit->clear();
86
87 ui->textEdit->appendPlainText("==元对象信息==\n");
88 ui->textEdit->appendPlainText(QString("类名称:%1\n").arg(meta->className()));
89
90 ui->textEdit->appendPlainText("property");
91 for (int i=meta->propertyOffset();i<meta->propertyCount();i++)
92 {
93 const char* propName=meta->property(i).name();
94 ui->textEdit->appendPlainText(
95 QString("属性名称=%1,属性值=%2").arg(propName).arg(boy->property(propName).toString()));
96 }
97
98 ui->textEdit->appendPlainText("");
99 ui->textEdit->appendPlainText("classInfo");
100 for (int i=meta->classInfoOffset();i<meta->classInfoCount();++i)
101 {
102 QMetaClassInfo classInfo=meta->classInfo(i);
103 ui->textEdit->appendPlainText(
104 QString("Name=%1; Value=%2").arg(classInfo.name()).arg(classInfo.value()));
105 }
106
107 }

qperson.cpp

 1 #include "qperson.h"
2
3 QPerson::QPerson(QString fName,QObject *parent) : QObject(parent)
4 { //构造函数
5 m_name=fName;
6 }
7
8 int QPerson::age()
9 { //返回age
10 return m_age;
11 }
12
13 void QPerson::setAge(int value)
14 {//设置age
15 m_age=value;
16 emit ageChanged(m_age); //发射信号
17 }
18
19 void QPerson::incAge()
20 {
21 m_age++;
22 emit ageChanged(m_age);//发射信号
23 }

[Qt]《开发指南》3.1源码分析的更多相关文章

  1. Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)

    一.Django请求生命周期: 前端发出请求到后端,通过Django处理.响应返回给前端相关结果的过程 先进入实现了wsgi协议的web服务器--->进入django中间件--->路由f分 ...

  2. FiddlerCoreAPI开发(一)源码分析

    1.前言 前一段时间想利用fiddlercore截取本地HTTPS的流量做一些分析,按照样例代码的注释学习了一下,没搞清楚怎么实现,后来又在网上查了些资料,对HTTPS的处理提及很少,都没有解决我的问 ...

  3. linux epoll 开发指南-【ffrpc源码解析】

    摘要 关于epoll的问题很早就像写文章讲讲自己的看法,但是由于ffrpc一直没有完工,所以也就拖下来了.Epoll主要在服务器编程中使用,本文主要探讨服务器程序中epoll的使用技巧.Epoll一般 ...

  4. Spring Security 源码分析(四):Spring Social实现微信社交登录

    社交登录又称作社会化登录(Social Login),是指网站的用户可以使用腾讯QQ.人人网.开心网.新浪微博.搜狐微博.腾讯微博.淘宝.豆瓣.MSN.Google等社会化媒体账号登录该网站. 前言 ...

  5. Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

    Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...

  6. Qt update刷新之源码分析(一)

    在做GUI开发时,要让控件刷新,会调用update函数:那么在调用了update函数后,Qt究竟基于什么原理.执行了什么代码使得屏幕上有变化?本文就带大家来探究探究其内部源码. Qt手册中关于QWid ...

  7. 移动web app开发必备 - Deferred 源码分析

    姊妹篇  移动web app开发必备 - 异步队列 Deferred 在分析Deferred之前我觉得还是有必要把老套的设计模式给搬出来,便于理解源码! 观察者模式 观察者模式( 又叫发布者-订阅者模 ...

  8. Qt源码分析之QObject

    原文:http://blog.csdn.net/oowgsoo/article/details/1529284 我感觉oowgsoo兄弟写的分析相当透彻,赞! 1.试验代码: #include < ...

  9. QT源码分析(从QApplication开始)

    QT源码分析 转载自:http://no001.blog.51cto.com/1142339/282130 今天,在给同学讲东西的时候,谈到了Qt源代码的问题,才发现自己对Qt机制的了解是在太少了,而 ...

  10. C# DateTime的11种构造函数 [Abp 源码分析]十五、自动审计记录 .Net 登陆的时候添加验证码 使用Topshelf开发Windows服务、记录日志 日常杂记——C#验证码 c#_生成图片式验证码 C# 利用SharpZipLib生成压缩包 Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库

    C# DateTime的11种构造函数   别的也不多说没直接贴代码 using System; using System.Collections.Generic; using System.Glob ...

随机推荐

  1. 力扣 - 92. 反转链表II

    目录 题目 思路1(迭代) 代码 复杂度分析 思路2(递归) 代码 复杂度分析 题目 92. 反转链表 II 思路1(迭代) 将反转链表分成3个部分:前一段未反转的部分.待反转链表部分.后一段未反转部 ...

  2. 自动QQ邮箱发送邮件

    语言:python 参考:https://www.runoob.com/python/python-email.html 前提: 1.QQ邮箱开启了SMTP服务 2.生成了授权码,这个授权码将作为自己 ...

  3. Node.js 包管理器 NPM 讲解

    包管理器又称软件包管理系统,它是在电脑中自动安装.配制.卸载和升级软件包的工具组合,在各种系统软件和应用软件的安装管理中均有广泛应用.对于我们业务开发也很受益,相同的东西不必重复去造轮子. 每个工具或 ...

  4. windows上phpstudy配置memcache

    原文   http://blog.csdn.net/ltx06/article/details/78588448   总的来说,分两步:同时安装memcached软件服务和安装php_memcache ...

  5. MySQL数据库高级五:主从复制

    主机只能一台 从机去复制 单表500万上限

  6. 在Visual Studio 中使用git——给Visual Studio安装 git插件(二)

    在Visual Studio 中使用git--什么是Git(一) 第二部分: 给Visual Studio安装 git插件 如果要使用 git 进行版本管理,其实使用 git 命令行工具就完全足够了, ...

  7. Day09_45_Set集合_SortedSet02

    SortedSet * TreeSet是SortedSet接口的实现类,TreeSet底层是一个TreeMap,相当于TreeMap中的key. * SortedSet集合是如何实现自动排序的呢? - ...

  8. .Net Core 集成 Kafka

    最近维护的一个系统并发有点高,所以想引入一个消息队列来进行削峰.考察了一些产品,最终决定使用kafka来当做消息队列.以下是关于kafka的一些知识的整理笔记. kafka kafka 是分布式流式平 ...

  9. Linux下查看CPU、内存占用率

    linux下查看最消耗CPU.内存的进程 CPU占用最多的前10个进程: ps auxw|head -1;ps auxw|sort -rn -k3|head -10 内存消耗最多的前10个进程: ps ...

  10. 路由器逆向分析------firmware-mod-kit工具安装和使用说明

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/68061957 一.firmware-mod-kit工具的安装 firmware-m ...