QtMeatObjectEx

Qt MeatObject Example
This commit is contained in:
touwoyimuli@gmail.com 2019-08-16 23:56:50 +08:00
parent 28a4a6f1bf
commit 20faa16653
7 changed files with 376 additions and 0 deletions

View File

@ -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); //发射信号
}

39
QtMeatObjectEx/ExPerson.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef EXPERSON_H
#define EXPERSON_H
#include <QObject>
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

106
QtMeatObjectEx/ExWidget.cpp Normal file
View File

@ -0,0 +1,106 @@
#include "ExWidget.h"
#include "ui_ExWidget.h"
#include <QMetaProperty>
#include <QDebug>
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<ExPerson *>(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<QSpinBox *>(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()));
}
}

35
QtMeatObjectEx/ExWidget.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef EXWIDGET_H
#define EXWIDGET_H
#include <QWidget>
#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

114
QtMeatObjectEx/ExWidget.ui Normal file
View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ExWidget</class>
<widget class="QWidget" name="ExWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>526</width>
<height>313</height>
</rect>
</property>
<property name="windowTitle">
<string>ExWidget</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="labBoy">
<property name="text">
<string>设置男生的年龄:</string>
</property>
</widget>
</item>
<item row="8" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="btnBoyAdd">
<property name="text">
<string>Boy:Age 增加</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QSpinBox" name="spinBoy">
<property name="value">
<number>20</number>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QPushButton" name="btnMetaObject">
<property name="text">
<string>类的元对象信息</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="labGril">
<property name="text">
<string>设置女生年龄</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QPushButton" name="btnClean">
<property name="text">
<string>清空文本框</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QPushButton" name="btnGrilAdd">
<property name="text">
<string>Girl:Age 增加</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QSpinBox" name="spinGril">
<property name="value">
<number>10</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="2">
<widget class="QPlainTextEdit" name="textEdit"/>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

View File

@ -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

11
QtMeatObjectEx/main.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "ExWidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ExWidget w;
w.show();
return a.exec();
}