From 20faa1665340cd808dcbfd933d12a1977b63c9e5 Mon Sep 17 00:00:00 2001 From: "touwoyimuli@gmail.com" Date: Fri, 16 Aug 2019 23:56:50 +0800 Subject: [PATCH] QtMeatObjectEx Qt MeatObject Example --- QtMeatObjectEx/ExPerson.cpp | 29 ++++++++ QtMeatObjectEx/ExPerson.h | 39 ++++++++++ QtMeatObjectEx/ExWidget.cpp | 106 +++++++++++++++++++++++++++ QtMeatObjectEx/ExWidget.h | 35 +++++++++ QtMeatObjectEx/ExWidget.ui | 114 ++++++++++++++++++++++++++++++ QtMeatObjectEx/QtMeatObjectEx.pro | 42 +++++++++++ QtMeatObjectEx/main.cpp | 11 +++ 7 files changed, 376 insertions(+) create mode 100644 QtMeatObjectEx/ExPerson.cpp create mode 100644 QtMeatObjectEx/ExPerson.h create mode 100644 QtMeatObjectEx/ExWidget.cpp create mode 100644 QtMeatObjectEx/ExWidget.h create mode 100644 QtMeatObjectEx/ExWidget.ui create mode 100644 QtMeatObjectEx/QtMeatObjectEx.pro create mode 100644 QtMeatObjectEx/main.cpp diff --git a/QtMeatObjectEx/ExPerson.cpp b/QtMeatObjectEx/ExPerson.cpp new file mode 100644 index 0000000..54756e2 --- /dev/null +++ b/QtMeatObjectEx/ExPerson.cpp @@ -0,0 +1,29 @@ +#include "ExPerson.h" + +//加一个参后的构造函数 +ExPerson::ExPerson(QString name, QObject *parent) : QObject(parent) +{ + m_name = name; +} + +int ExPerson::getAge() +{ + return m_age; +} + +void ExPerson::setAge(int value) +{ + m_age = value; + emit ageChanged(m_age); //发射信号 +} + +void ExPerson::incAge() +{ + m_age++; + emit ageChanged(m_age); //发射信号 +} + + + + + diff --git a/QtMeatObjectEx/ExPerson.h b/QtMeatObjectEx/ExPerson.h new file mode 100644 index 0000000..b60f695 --- /dev/null +++ b/QtMeatObjectEx/ExPerson.h @@ -0,0 +1,39 @@ +#ifndef EXPERSON_H +#define EXPERSON_H + +#include + +class ExPerson : public QObject +{ + Q_OBJECT + + //类的附加信息:名称————值 + Q_CLASSINFO("author", "touwoyimuli") + Q_CLASSINFO("version", "1.0.0") + Q_CLASSINFO("info", "Qt5 Meta Object and Property Example") + + //属性定义 + Q_PROPERTY(int age READ getAge WRITE setAge NOTIFY ageChanged) //属性age; 方法getAge()和setAge()对其读写; 设置信号ageChanged() + Q_PROPERTY(QString name MEMBER m_name) //属性name 与类成员变量m_name关联 + Q_PROPERTY(int score MEMBER m_score) //属性score与类成员变量m_score关联 + +public: + explicit ExPerson(QString name, QObject *parent = nullptr); + +public: + int getAge(); //属性 READ 函数 + void setAge(int value); //属性 WRITE 函数 + + void incAge(); //单独写一个接口,与属性无关 + +signals: + void ageChanged(int value); //属性age发生改变的信号函数 + +private: + int m_age = 5; + QString m_name; + int m_score = 50; + +}; + +#endif // EXPERSON_H diff --git a/QtMeatObjectEx/ExWidget.cpp b/QtMeatObjectEx/ExWidget.cpp new file mode 100644 index 0000000..ff84e12 --- /dev/null +++ b/QtMeatObjectEx/ExWidget.cpp @@ -0,0 +1,106 @@ +#include "ExWidget.h" +#include "ui_ExWidget.h" +#include +#include + +ExWidget::ExWidget(QWidget *parent) : QWidget(parent), ui(new Ui::ExWidget) +{ + ui->setupUi(this); + + m_boy = new ExPerson("张三"); + m_boy->setProperty("score", 90); + m_boy->setProperty("age", 20); + m_boy->setProperty("sex", "Boy"); //动态属性 + connect(m_boy, &ExPerson::ageChanged, this, &ExWidget::onAgeChange); + + m_girl = new ExPerson("张丽"); + m_girl->setProperty("score", 80); + m_girl->setProperty("age", 10); + m_girl->setProperty("sex", "Gril"); //动态属性 + connect(m_girl, &ExPerson::ageChanged, this, &ExWidget::onAgeChange); + + ui->spinBoy->setProperty("isBoy", true); //动态属性 + ui->spinGril->setProperty("isBoy", false); + + connect(ui->spinGril, SIGNAL(valueChanged(int)), this, SLOT(onSpinValChange(int))); + connect(ui->spinBoy, SIGNAL(valueChanged(int)), this, SLOT(onSpinValChange(int))); + + connect(ui->btnBoyAdd, SIGNAL(clicked()), this, SLOT(onBtnBoyInc())); + connect(ui->btnGrilAdd, SIGNAL(clicked()), this, SLOT(onBtnGrilInc())); + connect(ui->btnMetaObject, SIGNAL(clicked()), this, SLOT(onClassInfo())); + connect(ui->btnClean, SIGNAL(clicked()), this, SLOT(onBtnClear())); + + setWindowTitle(QObject::tr("元对象MetaObject和(含动态)属性Propert的用法")); +} + +ExWidget::~ExWidget() +{ + delete ui; +} + +void ExWidget::onAgeChange(int val) +{ + Q_UNUSED(val) //参数val没使用,避免警告 + + ExPerson* person = qobject_cast(sender()); //类型投射 + QString name = person->property("name").toString(); + QString sex = person->property("sex").toString(); + int age = person->getAge(); //通过接口函数,获得年龄 + //或使用 int age = person->property("age").toInt(); + ui->textEdit->appendPlainText(name+","+sex + QString::asprintf(",年龄=%d",age)); +} + +void ExWidget::onSpinValChange(int val) +{ + Q_UNUSED(val) + + QSpinBox* spin = qobject_cast(sender()); //类型投射 + if (spin->property("isBoy").toBool()) + m_boy->setAge(ui->spinBoy->value()); + else + m_girl->setAge(ui->spinGril->value()); +} + +void ExWidget::onBtnClear() +{ + ui->textEdit->clear(); +} + +void ExWidget::onBtnBoyInc() +{ + m_boy->incAge(); +} + +void ExWidget::onBtnGrilInc() +{ + m_girl->incAge(); +} + +void ExWidget::onClassInfo() +{ + const QMetaObject* meta = m_boy->metaObject(); + + ui->textEdit->clear(); + ui->textEdit->appendPlainText("==元对象信息(Meta Object)==="); + ui->textEdit->appendPlainText(QString("类名称: %1\n").arg(meta->className())); + ui->textEdit->appendPlainText("属性(property)"); + + for (int i = meta->propertyOffset(); i < meta->propertyCount(); i++) + { + QMetaProperty prop = meta->property(i); + const char* propName = prop.name(); + QString propValue = m_boy->property(propName).toString(); + ui->textEdit->appendPlainText(QString("属性名称=%1, 属性值= %2").arg(propName).arg(propValue)); + } + + ui->textEdit->appendPlainText(""); + ui->textEdit->appendPlainText("classInfo:"); + for (int i = meta->classInfoOffset(); i < meta->classInfoCount(); i++) + { + QMetaClassInfo classInfo = meta->classInfo(i); + ui->textEdit->appendPlainText(QString("Name=%1, Value= %2").arg(classInfo.name()).arg(classInfo.value())); + } + +} + + diff --git a/QtMeatObjectEx/ExWidget.h b/QtMeatObjectEx/ExWidget.h new file mode 100644 index 0000000..96933f7 --- /dev/null +++ b/QtMeatObjectEx/ExWidget.h @@ -0,0 +1,35 @@ +#ifndef EXWIDGET_H +#define EXWIDGET_H + +#include +#include "ExPerson.h" + +namespace Ui { +class ExWidget; +} + +class ExWidget : public QWidget +{ + Q_OBJECT + +public: + explicit ExWidget(QWidget *parent = nullptr); + ~ExWidget(); + +private slots: + void onAgeChange(int val); //自定义的槽函数 + void onSpinValChange(int val); + + void onBtnClear(); //UI界面的槽函数 + void onBtnBoyInc(); + void onBtnGrilInc(); + void onClassInfo(); + +private: + Ui::ExWidget *ui; + + ExPerson* m_boy; + ExPerson* m_girl; +}; + +#endif // EXWIDGET_H diff --git a/QtMeatObjectEx/ExWidget.ui b/QtMeatObjectEx/ExWidget.ui new file mode 100644 index 0000000..e3af340 --- /dev/null +++ b/QtMeatObjectEx/ExWidget.ui @@ -0,0 +1,114 @@ + + + ExWidget + + + + 0 + 0 + 526 + 313 + + + + ExWidget + + + + + + + + 设置男生的年龄: + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Boy:Age 增加 + + + + + + + 20 + + + + + + + 类的元对象信息 + + + + + + + 设置女生年龄 + + + + + + + 清空文本框 + + + + + + + Girl:Age 增加 + + + + + + + 10 + + + + + + + + + + + + + + diff --git a/QtMeatObjectEx/QtMeatObjectEx.pro b/QtMeatObjectEx/QtMeatObjectEx.pro new file mode 100644 index 0000000..556e362 --- /dev/null +++ b/QtMeatObjectEx/QtMeatObjectEx.pro @@ -0,0 +1,42 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2019-08-16T20:47:42 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = QtMeatObjectEx +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +CONFIG += c++11 + +SOURCES += \ + main.cpp \ + ExWidget.cpp \ + ExPerson.cpp + +HEADERS += \ + ExWidget.h \ + ExPerson.h + +FORMS += \ + ExWidget.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/QtMeatObjectEx/main.cpp b/QtMeatObjectEx/main.cpp new file mode 100644 index 0000000..ab25a7f --- /dev/null +++ b/QtMeatObjectEx/main.cpp @@ -0,0 +1,11 @@ +#include "ExWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + ExWidget w; + w.show(); + + return a.exec(); +}