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);
    }
}

效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

castlooo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值