TPerson发射信号Signal,Dialog槽函数实现,类元数据实现

实验目的

创建TPerson类,年龄增加事件发射信号

创建Dailog窗体,将TPerson类发射来的信号,绑定到窗体槽函数

使用QMetaObject显示类元数据 ,显示类名称,遍历类属性Property名称及属性值,

遍历打印类元数据的 classInfo信息

TPerson类

tperson.h

声明ageChanged信号 

 

#ifndef TPERSON_H
#define TPERSON_H

#include <QObject>

class TPerson : public QObject
{
    Q_OBJECT
    Q_CLASSINFO("author","cc")
    Q_CLASSINFO("company","companyC")
    Q_CLASSINFO("version","1.0.0")

    //定义age属性
    Q_PROPERTY(int age READ age WRITE setAge NOTIFY ageChanged FINAL)
    Q_PROPERTY(int score MEMBER m_score)
    Q_PROPERTY(QString name MEMBER m_Name)

private:
    int m_age=10;
    int m_score=79;
    QString m_Name;

public:
    explicit TPerson(QString aName, QObject *parent = nullptr);
    ~TPerson();

    int age();
    int setAge(int value);
    void incAge();

signals:
    void ageChanged(int value);
};

#endif // TPERSON_H

tperson.cpp

 在incAge方法中emit发射信号

#include "tperson.h"


TPerson::TPerson(QString aName,QObject *parent):QObject(parent)
{
    this->m_Name = aName;
}
TPerson::~TPerson()
{
    //析构函数
}

int TPerson::age()
{
    return this->m_age;
}

int TPerson::setAge(int value){
    this->m_age = value;
    emit ageChanged(this->m_age); //发射信号  用于后面绑定界面变化的槽来执行
}

void TPerson::incAge()
{
    this->m_age++;
    emit ageChanged(this->m_age);
}

Dialog

dialog.h

声明do_ageChanged执行方法 

#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include "tperson.h"


QT_BEGIN_NAMESPACE
namespace Ui {
class Dialog;
}
QT_END_NAMESPACE

class Dialog: public QDialog
{
    Q_OBJECT
public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();
private slots:
    void do_ageChanged(int value);
    void do_spinChanged(int value);

    void on_btnClassInfo_clicked();

    void on_btnClear_clicked();

    void on_btnGirlInc_clicked();

    void on_btnBoyInc_clicked();

private:
    TPerson *boy;
    TPerson *girl;

    Ui::Dialog *ui;

};



#endif // DIALOG_H

dialog.cpp

 通过connect 将&TPerson::ageChanged方法 ,将信号连接到槽执行方法:本类中&Dialog::do_agedChanged

#include    "dialog.h"
#include    "ui_dialog.h"
#include "tperson.h"
#include "QMetaProperty"

Dialog::Dialog(QWidget *parent):
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    //初始化数据
    boy = new TPerson("张铁蛋",this);
    boy->setProperty("score",94);
    boy->setProperty("age",11);
    boy->setProperty("gender","Boy");
    connect(boy,&TPerson::ageChanged,this,&Dialog::do_ageChanged); //将类发送过来的信号,传递到窗体类中槽执行函数

    girl = new TPerson("李丽",this);
    girl->setProperty("score",98);
    girl->setProperty("age",12);
    girl->setProperty("gender","Girl");  // 添加一个动态属性 gender
    connect(girl,&TPerson::ageChanged,this,&Dialog::do_ageChanged);

    ui->spinBoy->setProperty("isBoy",true);//在spinBox中添加一个动态属性isBoy
    ui->spinGirl->setProperty("isBoy",false);

    //将spinBoy、SpinGirl的valueChanged事件 绑定到 本类中的槽执行函数
    connect(ui->spinBoy,&QSpinBox::valueChanged,this,&Dialog::do_spinChanged);
    connect(ui->spinGirl,&QSpinBox::valueChanged,this,&Dialog::do_spinChanged);


}
Dialog::~Dialog()
{
    delete ui;
}

//girl长大一岁
void Dialog::on_btnGirlInc_clicked()
{
    girl->incAge();// TPerson→incAge →emit ageChanged→connet this  do_ageChanged
}

//Boy长大一岁
void Dialog::on_btnBoyInc_clicked()
{
    boy->incAge();
}

void Dialog::do_ageChanged(int value)
{
//Q_UNUSED()函数在程序中的作用,就如它所代表的英文一样,unused,即无用的意思。即Q_UNUSED()函数在程序中没有实质性的作用,用来避免编译器警告。
    Q_UNUSED(value);
    TPerson *person = qobject_cast<TPerson *>(sender());
    QString hisName= person->property("name").toString();
    QString hisGender = person->property("gender").toString();
    int hisAge = person->property("age").toInt();
    QString str = QString("%1,%2,年龄=%3").arg(hisName).arg(hisGender).arg(hisAge);
    ui->textBox->appendPlainText(str);

}


void Dialog::do_spinChanged(int value)
{
    QSpinBox *spin = qobject_cast<QSpinBox *>(sender());//获取信号发射者
    if(spin->property("isBoy").toBool()){//根据发送过来自定义动态属性 判断 是哪个组件
        boy->setAge(value);
    }
    else {
        girl->setAge(value);
    }
}


void Dialog::on_btnClear_clicked()
{
    ui->textBox->clear();
}

void Dialog::on_btnClassInfo_clicked()
{
    QObject *obj =boy;
    const QMetaObject *meta = obj->metaObject();
    ui->textBox->clear();
    ui->textBox->appendPlainText(QString("类名称:%1").arg(meta->className()));
    ui->textBox->appendPlainText("property");
    //获取类属性及属性值
    for(int i=meta->propertyOffset();i<meta->propertyCount();i++)
    {
        const char* propName=meta->property(i).name();
        QString propValue= obj->property(propName).toString();
        QString str=QString("属性名称%1,属性值%2").arg(propName).arg(propValue);
        ui->textBox->appendPlainText(str);
    }

    //获取类信息
    ui->textBox->appendPlainText("");
    ui->textBox->appendPlainText("classInfo");
    for(int i=meta->classInfoOffset();i<meta->classInfoCount();i++)
    {
        QMetaClassInfo classInfo =meta->classInfo(i);
        QString str= QString("ClassInfo Name=%1, Value=%2").arg(classInfo.name()).arg(classInfo.value());
        ui->textBox->appendPlainText(str);
    }
}

类的元信息

 通过QMetaObject 来遍历Property属性,打印属性名称,属性值,需要引用QMetaProperty

#include "QMetaProperty"

 通过 QMetaClassInfo获取meta的CalssInfo

void Dialog::on_btnClassInfo_clicked()
{
    QObject *obj =boy;
    const QMetaObject *meta = obj->metaObject();
    ui->textBox->clear();
    ui->textBox->appendPlainText(QString("类名称:%1").arg(meta->className()));
    ui->textBox->appendPlainText("property");
    //获取类属性及属性值
    for(int i=meta->propertyOffset();i<meta->propertyCount();i++)
    {
        const char* propName=meta->property(i).name();
        QString propValue= obj->property(propName).toString();
        QString str=QString("属性名称%1,属性值%2").arg(propName).arg(propValue);
        ui->textBox->appendPlainText(str);
    }

    //获取类信息
    ui->textBox->appendPlainText("");
    ui->textBox->appendPlainText("classInfo");
    for(int i=meta->classInfoOffset();i<meta->classInfoCount();i++)
    {
        QMetaClassInfo classInfo =meta->classInfo(i);
        QString str= QString("ClassInfo Name=%1, Value=%2").arg(classInfo.name()).arg(classInfo.value());
        ui->textBox->appendPlainText(str);
    }
}

效果

相关推荐

  1. 实现信号发生控制

    2024-06-14 12:52:02       27 阅读
  2. PyQt中的信号/以及纯python实现信号/设计模式

    2024-06-14 12:52:02       59 阅读
  3. Qt5自定义信号实现方式

    2024-06-14 12:52:02       42 阅读
  4. 纯Python实现Qt的信号机制

    2024-06-14 12:52:02       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-14 12:52:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-14 12:52:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-06-14 12:52:02       82 阅读
  4. Python语言-面向对象

    2024-06-14 12:52:02       91 阅读

热门阅读

  1. 软件设计模式概述

    2024-06-14 12:52:02       27 阅读
  2. Linux之逻辑控制符&&

    2024-06-14 12:52:02       30 阅读
  3. 带你学习Mybatis之执行器Executor

    2024-06-14 12:52:02       28 阅读
  4. 聊聊C/S模式架构的优缺点

    2024-06-14 12:52:02       33 阅读
  5. 面试题(常见)

    2024-06-14 12:52:02       34 阅读
  6. Webrtc支持FFMPEG硬解码之NVIDA(二)

    2024-06-14 12:52:02       35 阅读
  7. 字节一面(年前)测开—飞书

    2024-06-14 12:52:02       30 阅读
  8. 代码详解工厂设计模式【2】

    2024-06-14 12:52:02       30 阅读
  9. NumPy 字节交换

    2024-06-14 12:52:02       27 阅读
  10. 未来展望:超越现实的边界

    2024-06-14 12:52:02       20 阅读
  11. 2024-03 GESP C++ 六级试题及答案

    2024-06-14 12:52:02       24 阅读