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); }
- 最终界面样式
-