• 自定义的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. 自定义类、自定义信号及类的元对象信息的更多相关文章

  1. python类的继承和多态,获取对象信息

    继承 类的继承机制使得子类可以继承父类中定义的方法,拥有父类的财产,比如有一个Animal的类作为父类,它有一个eat方法: class Animal(object): def __init__(se ...

  2. Qt笔记——元对象系统

    Qt元对象系统提供了对象间的通信机制:信号和槽.以及执行类形信息和动态属性系统的支持.是标注C++的一个扩展,它使得Qt可以更好的实现GUI图形用户界面编程.Qt的元对象系统不支持C++模板.虽然模板 ...

  3. spring笔记--使用springAPI以及自定义类 实现AOP的一个例子

    Spring的另一个重要思想是AOP,面向切面的编程,它提供了一种机制,可以在执行业务前后执行另外的代码,Servlet中的Filter就是一种AOP思想的体现,下面通过一个例子来感受一下. 假设我们 ...

  4. iOS回顾笔记(03) -- 自定义View的封装和xib文件的使用详解

    iOS回顾笔记(03) -- 自定义View的封装和xib文件的使用详解 iOS开发中,我们常常将一块View封装起来,以便于统一管理内部的子控件.如iOS回顾笔记(02)中的"书" ...

  5. iOS回顾笔记(08) -- 自定义Cell的类型和创建步骤总结

    iOS回顾笔记(08) -- 自定义Cell的类型和创建步骤总结 项目中我们常见的自定义cell主要分为两种 等高cell:如应用列表.功能列表 非等高cell:如微博列表.QQ聊天页面 下面对这 ...

  6. Hadoop学习笔记—9.Partitioner与自定义Partitioner

    一.初步探索Partitioner 1.1 再次回顾Map阶段五大步骤 在第四篇博文<初识MapReduce>中,我们认识了MapReduce的八大步凑,其中在Map阶段总共五个步骤,如下 ...

  7. 自定义能够for each的类,C#,Java,C++,C++/cli的实现方法

    自定义类能够被for each,应该算是个老生常谈的话题了,相关的资料都很多,不过这里整理总结主流语言的不同实现方式,并比较部分细节上的差异. 第一种语言,也是实现起来最简单的Java语言.在Java ...

  8. SpringBoot + Spring Security 学习笔记(一)自定义基本使用及个性化登录配置

    官方文档参考,5.1.2 中文参考文档,4.1 中文参考文档,4.1 官方文档中文翻译与源码解读 SpringSecurity 核心功能: 认证(你是谁) 授权(你能干什么) 攻击防护(防止伪造身份) ...

  9. Angularjs进阶笔记(2)-自定义指令中的数据绑定

    有关自定义指令的scope参数,网上很多文章都在讲这3种绑定方式实现的效果是什么,但几乎没有人讲到底怎么使用,本篇希望聊聊到底怎么用这个话题. 一. 自定义指令 自定义指令,是Angularjs用来实 ...

  10. 模仿CountDownLatch类自定义倒时计时器

    简介 这里模仿CountDownLatch类自定义到时计时器,利用AQS模板中的尝试获得共享和释放共享 1.MyCountDownLatch package com.jacky; import com ...

随机推荐

  1. TaurusDB库表时间点极速恢复,大幅缩短数据恢复时间

    经过多组实验对比,对于大实例下仅需恢复几张表数据的情况,有显著优化效果.尤其针对游戏业务等需要频繁回档的场景,将大幅度缩短因数据恢复导致的停服时间.后续我们将逐步在公有云上开放此特性,以惠及更多用户. ...

  2. ChatGPT生成接口测试用例(二)

    5.1.4 自动生成测试数据 测试数据的生成通常是接口测试的一个烦琐任务.ChatGPT可以帮助测试团队生成测试数据,包括各种输入和它们的组合.测试人员可以描述他们需要的数据类型和范围,ChatGPT ...

  3. 解锁 Git Log 更多实用技巧

    目前,在软件开发的协作中,Git 无疑是版本控制的王者. 而其中的 git log 命令,犹如一把强大的历史探寻之剑,能够帮助我们深入洞察项目的演进历程. 本篇将为大家整理解读几个实用的 git Lo ...

  4. opencv+Linux源码编译安装及引用

    (一)下载 opencv下载地址:https://opencv.org/releases/ opencv_contrib下载地址:https://github.com/opencv/opencv_co ...

  5. Qt编写可视化大屏电子看板系统24-模块2当月计划

    一.前言 延续分层模块化的设计思路,当月计划模块主要包括模具达成率.零件达成率.零件数.每日工序达成数5个子模块,其中模具达成率采用自定义控件环形图展示,比如计划多少达成多少,达成作为进度:零件达成率 ...

  6. Qt音视频开发22-通用GPU显示

    一.前言 采用GPU来绘制实时视频一直以来都是个难点,如果是安防行业的做视频监控开发这块的人员,这个坎必须迈过去,本人一直从事的是安防行业的电子围栏这个相当小众的细分市场的开发,视频监控这块仅仅是周边 ...

  7. 手写 PromiseA+ 实现,轻松通过 872 条用例

    手写 Promise/A+ 实现,轻松通过 872 条用例 规范参考:Promise/A+ 规范 - 中文版本 测试工具:https://github.com/promises-aplus/promi ...

  8. [转]Clion+mingw环境下Assimp编译

    1.Clion+mingw环境下Assimp编译 2.MinGW-w64下载

  9. 记一次 .NET某汗液测试机系统 崩溃分析

    一:背景 1. 讲故事 上个月在社区写的文章比较少,一直关注的朋友应该知道那段时间被狗咬了以及一些琐事处理,所以手头上也攒了不少需要分享的案例,这段时间比较空闲,逐个给大 家做个分享吧,刚好年后为新版 ...

  10. JVM实战—12.OOM的定位和解决

    大纲 1.如何对系统的OOM异常进行监控和报警 2.如何在JVM内存溢出时自动dump内存快照 3.Metaspace区域内存溢出时应如何解决(OutOfMemoryError: Metaspace) ...