QT5笔记:7. 自定义类、自定义信号及类的元对象信息
自定义的QPerson类,需要继承 QObject类
qperson.h头文件
#ifndef QPERSON_H
#define QPERSON_H #include <QObject> class QPerson : public QObject
{
Q_OBJECT
Q_CLASSINFO("author", "……");
Q_CLASSINFO("company", "……");
Q_CLASSINFO("version", "1.0");
Q_PROPERTY(unsigned int age READ age WRITE setAge NOTIFY ageChanged);
Q_PROPERTY(QString name MEMBER m_name);
Q_PROPERTY(int score MEMBER m_score); public:
explicit QPerson(QString name, QObject *parent = nullptr);
unsigned int age();
void setAge(unsigned int val);
void increaseAge(); private:
unsigned int m_age = 10;
QString m_name;
int m_score = 80; signals:
void ageChanged(int age);//自定义的信号
}; #endif // QPERSON_H
qperson.cpp 类文件
#include "qperson.h" QPerson::QPerson(QString name, QObject *parent) : QObject(parent)
{
m_name = name;
} unsigned int QPerson::age()
{
return m_age;
} void QPerson::setAge(unsigned int val)
{
if (val != m_age)//当变化时设置值并发射信号
{
m_age = val;
emit(ageChanged(m_age));//发射信号
}
} void QPerson::increaseAge()
{
m_age++;
emit(ageChanged(m_age));//发射信号
}widget.h 界面的头文件
#ifndef WIDGET_H
#define WIDGET_H #include <QWidget>
#include "qperson.h" //自己创建的类,用双引号引入 QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE class Widget : public QWidget
{
Q_OBJECT public:
Widget(QWidget *parent = nullptr);
~Widget(); private slots: //信号&槽不同于方法,需要写在头文件的这里 private slots
void on_btnAddBoyAge_clicked(); void on_btnAddGirlAge_clicked(); void on_btnMetaInfo_clicked(); void on_spin_valueChanged(int val); void on_ageChanged(int age); private:
Ui::Widget *ui;
QPerson *boy;
QPerson *girl;
};
#endif // WIDGET_H
- widget.cpp 界面的类文件
#include "widget.h"
#include "ui_widget.h"
#include <QMetaProperty> Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
ui->spinBoxBoyAge->setProperty("isBoy", true);// 类似于WinForm 的Tag,但是比Tag强大,键值对类型
ui->spinBoxGirlAge->setProperty("isBoy", false); boy = new QPerson("张三");
boy->setAge(12);
boy->setProperty("score", 99);
boy->setProperty("sex", "boy"); //动态属性
// connect(boy, &QPerson::ageChanged, this, &Widget::on_ageChanged);
connect(boy, SIGNAL(ageChanged(int)), this, SLOT(on_ageChanged(int)));//链接自定义函数 girl = new QPerson("蕾欧娜");
girl->setAge(15);
girl->setProperty("score", 120);
girl->setProperty("sex", "girl"); //动态属性
connect(girl, SIGNAL(ageChanged(int)), this, SLOT(on_ageChanged(int))); connect(ui->spinBoxBoyAge, SIGNAL(valueChanged(int)), this, SLOT(on_spin_valueChanged(int)));
connect(ui->spinBoxGirlAge, SIGNAL(valueChanged(int)), this, SLOT(on_spin_valueChanged(int)));
} Widget::~Widget()
{
delete ui;
} void Widget::on_btnAddBoyAge_clicked()
{
boy->increaseAge();
} void Widget::on_btnAddGirlAge_clicked()
{
girl->increaseAge();
} /**
* @brief Widget::on_btnMetaInfo_clicked 元对象信息:对象信息和类的信息
*/
void Widget::on_btnMetaInfo_clicked()
{
ui->textBoxInfo->clear();
const QMetaObject *metaGirl = girl->metaObject();
ui->textBoxInfo->appendPlainText("【对象信息】");
ui->textBoxInfo->appendPlainText(QString("类名称:%1").arg(metaGirl->className()));
QString text = QString::Null();
for (int i = metaGirl->propertyOffset(); i < metaGirl->propertyCount(); i++)//属性的获取方式
{
QMetaProperty property = metaGirl->property(i);
const char *name = property.name();
QString value = girl->property(name).toString();
text += QString("属性名:%1").arg(name) + "\t值:" + value + "\n";//字符串的拼接
}
ui->textBoxInfo->appendPlainText(text);
ui->textBoxInfo->appendPlainText("【类信息】");
QString classInfo = QString::Null();
for (int i = metaGirl->classInfoOffset(); i < metaGirl->classInfoCount(); i++)
{
QMetaClassInfo classInf = metaGirl->classInfo(i);
const char *name = classInf.name();
const char *value = classInf.value();
classInfo += QString("属性名:%1\t值:%2\n").arg(name).arg(value);//格式化字符串拼接函数
}
ui->textBoxInfo->appendPlainText(classInfo);
} void Widget::on_spin_valueChanged(int val)
{
Q_UNUSED(val);//标明这个变量unused
QSpinBox *box = qobject_cast<QSpinBox *>(sender());//类似于WinForm 的事件里的sender,一样需要类型转换,并且类型不匹配时返回null
if (box->property("isBoy").toBool())
boy->setAge(box->value());
else
girl->setAge(box->value());
} void Widget::on_ageChanged(int age)
{
Q_UNUSED(age);//标明这个变量unused
QPerson *person = qobject_cast<QPerson *>(sender());
QString name = person->property("name").toString();
QString sex = person->property("sex").toString();
unsigned int p_age = person->age();
ui->textBoxInfo->appendPlainText("姓名:" + name + " ,性别:" + sex + ", 年龄:" + QString::asprintf("%d", p_age));//格式化输出 if (person->property("sex").toString() == "boy")
ui->spinBoxBoyAge->setValue(p_age);
else
ui->spinBoxGirlAge->setValue(p_age);
}- 最终界面样式
QT5笔记:7. 自定义类、自定义信号及类的元对象信息的更多相关文章
- python类的继承和多态,获取对象信息
继承 类的继承机制使得子类可以继承父类中定义的方法,拥有父类的财产,比如有一个Animal的类作为父类,它有一个eat方法: class Animal(object): def __init__(se ...
- Qt笔记——元对象系统
Qt元对象系统提供了对象间的通信机制:信号和槽.以及执行类形信息和动态属性系统的支持.是标注C++的一个扩展,它使得Qt可以更好的实现GUI图形用户界面编程.Qt的元对象系统不支持C++模板.虽然模板 ...
- spring笔记--使用springAPI以及自定义类 实现AOP的一个例子
Spring的另一个重要思想是AOP,面向切面的编程,它提供了一种机制,可以在执行业务前后执行另外的代码,Servlet中的Filter就是一种AOP思想的体现,下面通过一个例子来感受一下. 假设我们 ...
- iOS回顾笔记(03) -- 自定义View的封装和xib文件的使用详解
iOS回顾笔记(03) -- 自定义View的封装和xib文件的使用详解 iOS开发中,我们常常将一块View封装起来,以便于统一管理内部的子控件.如iOS回顾笔记(02)中的"书" ...
- iOS回顾笔记(08) -- 自定义Cell的类型和创建步骤总结
iOS回顾笔记(08) -- 自定义Cell的类型和创建步骤总结 项目中我们常见的自定义cell主要分为两种 等高cell:如应用列表.功能列表 非等高cell:如微博列表.QQ聊天页面 下面对这 ...
- Hadoop学习笔记—9.Partitioner与自定义Partitioner
一.初步探索Partitioner 1.1 再次回顾Map阶段五大步骤 在第四篇博文<初识MapReduce>中,我们认识了MapReduce的八大步凑,其中在Map阶段总共五个步骤,如下 ...
- 自定义能够for each的类,C#,Java,C++,C++/cli的实现方法
自定义类能够被for each,应该算是个老生常谈的话题了,相关的资料都很多,不过这里整理总结主流语言的不同实现方式,并比较部分细节上的差异. 第一种语言,也是实现起来最简单的Java语言.在Java ...
- SpringBoot + Spring Security 学习笔记(一)自定义基本使用及个性化登录配置
官方文档参考,5.1.2 中文参考文档,4.1 中文参考文档,4.1 官方文档中文翻译与源码解读 SpringSecurity 核心功能: 认证(你是谁) 授权(你能干什么) 攻击防护(防止伪造身份) ...
- Angularjs进阶笔记(2)-自定义指令中的数据绑定
有关自定义指令的scope参数,网上很多文章都在讲这3种绑定方式实现的效果是什么,但几乎没有人讲到底怎么使用,本篇希望聊聊到底怎么用这个话题. 一. 自定义指令 自定义指令,是Angularjs用来实 ...
- 模仿CountDownLatch类自定义倒时计时器
简介 这里模仿CountDownLatch类自定义到时计时器,利用AQS模板中的尝试获得共享和释放共享 1.MyCountDownLatch package com.jacky; import com ...
随机推荐
- 【相邻不同型贪心】LeetCode767 重构字符串
题解 通常直接思考最佳策略是十分困难的,我们不妨思考每一种情况需要如何处理: 整个字符串只有一种字符 若字符串长度为 \(1\),那么字符串本身即为答案: 若字符串长度大于等于 \(2\),那么不存在 ...
- openEuler欧拉安装Gitlab
1. 安装GitLab wget https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh sud ...
- 【CLS数据淘金第四期】网络流日志-云联网日志分析
导语 云联网(Cloud Connect Network,CCN)云联网覆盖全球 20+ 地域,提供云上私有网络间(VPC).VPC 与本地数据中心间(IDC)内网互联的服务,具备全网多点互联.路由自 ...
- ChatGPT生成接口测试用例(一)
接口测试在软件开发生命周期中扮演着至关重要的角色,有助于验证不同模块之间的交互是否正确.若协议消息被恶意修改,系统是否能够恰当处理,以确保系统的功能正常运行,不会出现宕机或者安全问题. 5.1 Cha ...
- 【分享】记一次项目迁移(docker java | docker python)
项目:前端Vue3,后端Python+Java,数据库Redis+MySQL 原先部署在centos7里面的,使用的宝塔面板部署的,还算方便. 但是服务器要到期了,要将项目迁移到另外一台服务器. 另外 ...
- jQuery ajax - serializeArray() 方法 实例表单提交
serializeArray()在ajax表单提交时候非常方便获取元素 定义和用法 serializeArray() 方法通过序列化表单值来创建对象数组(名称和值). 您可以选择一个或多个表单元素(比 ...
- Qt编写视频监控系统74-悬浮工具栏(半透明/上下左右位置/自定义按钮)
一.前言 在监控系统中一般在视频实时预览的时候,希望提供一个悬浮工具条,可以显示一些提示信息比如分辨率.码率.帧率,提供一堆快捷操作按钮,可以录像.抓拍.云台控制.关闭等操作,参考了国内很多监控厂商客 ...
- SpringBoot进阶教程(八十四)spring-retry
在日常的一些场景中, 很多需要进行重试的操作.而spring-retry是spring提供的一个基于spring的重试框架,某些场景需要对一些异常情况下的方法进行重试就会用到spring-retry. ...
- HTTP方法-GET对比POST
什么是 HTTP ? 超文本传输协议(HTTP)的设计目的是保证客户端与服务器之间的通信. HTTP 的工作方式是客户端与服务器之间的请求-应答协议. web 浏览器可能是客户端,而计算机上的网络应用 ...
- ClickHouse-1介绍
https://clickhouse.com/docs/zh/ 一.clickhouse简介 ClickHouse 是俄罗斯的Yandex开源的用于在线分析处理查询(OLAP :Online Anal ...