QT系列第2节 QT中元对象系统

      QT是在标准C++上进行了扩展,所以就有自己的特性,其中元对象系统就是其一。元对象系统有点类似于java和go语言中的反射,让我们在编程时解决问题多了些方法和思路,关于元对象可以简单总结出以下内容项。

目录

一.元对象要点总结

二. 示例代码


一.元对象要点总结

1. QObject类是所有使用元对象系统的基类

2.在一个类private区域中声明Q_OBJECT宏,MOC(元对象编译器)为每个继承(直接或者间接)Object的类生成额外代码

3. qobject_cast:QT中的强制类型转换方法

4.属性系统 Q_PROPERTY宏定义一个返回类型为type,名称为name的属性,例如:

Q_PROPERTY(type name (...))

5.setProperty可以在运行时为对象定义一个新的属性,该属性称之为动态属性

6.Q_CLASSINFO可以增加类的附加信息,例如:Q_CLASSINFO("name", "zhangsan")

二. 示例代码

接下来用一个小demo演示一下元对象的简单应用。项目目录结构结构如下:
QT系列第2节 QT中元对象系统_第1张图片

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include "qperson.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void onAdd();
    void onSub();
    void onMetaInfo();
    void onAgeChanged(unsigned age);
    void on_spinBoxFeMale_valueChanged(int arg1);

    void on_spinBoxMale_valueChanged(int arg1);

    void on_pushButtonMetaInfo_clicked();

    void on_pushButtonAdd_clicked();

    void on_pushButtonSub_clicked();

private:
    Ui::MainWindow *ui;
    QPerson* m_male;
    QPerson* m_feMale;
};
#endif // MAINWINDOW_H

qperson.h

#ifndef QPERSON_H
#define QPERSON_H

#include 

class QPerson : public QObject
{
    Q_OBJECT
Q_CLASSINFO("author", "Zhangsan")
Q_CLASSINFO("company", "ABC")
Q_CLASSINFO("version", "1.0.0.1")
    Q_PROPERTY(unsigned 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 age();
    void setAge(unsigned age);
    void ageAdd(unsigned age);
    void ageSub(unsigned age);
    QString getName();

private:
unsigned m_age = 18;
QString m_name = "lisi";
int m_score = 85;

signals:
    void ageChanged(unsigned age);

};

#endif // QPERSON_H

main.cpp

#include "mainwindow.h"

#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
#include 
#include 
#include 

//元对象系统(Meta-Object System)
//QObject类是所有使用元对象系统的基类
// 在一个类private区域中声明Q_OBJECT宏
// MOC(元对象编译器)为每个继承(直接或者间接)Object的类生成额外代码

//qobject_cast:强制类型转换

//属性系统 Q_PROPERTY宏定义一个返回类型为type,名称为name的属性
//Q_PROPERTY(type name (...))

//setProperty可以在运行时为类定义一个新的属性,称之为动态属性

//类的附加信息 Q_CLASSINFO("name", "zhangsan")
//QTest* pTest = new QTest;
//qDebug << pTest->metaObject()->classInfo(0).name(); //"name"
//qDebug << pTest->metaObject()->classInfo(0).value(); //"zhangsan"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QObject* obj = new QPushButton();
    qDebug() << obj->metaObject()->className();

    QLineEdit* edit = new QLineEdit;
    qDebug() << edit->inherits("QDebug");
    qDebug() << edit->inherits("QObject");

    m_male = new QPerson("帅男人");
    m_male->setProperty("addr", "北京");
    m_male->setProperty("income", 10000);
    m_male->setProperty("height", 180);
    connect(m_male, &QPerson::ageChanged, this, &MainWindow::onAgeChanged);

    m_feMale = new QPerson("靓女人");
    m_feMale->setProperty("addr", "上海");
    m_feMale->setProperty("income", 8000);
    m_feMale->setProperty("height", 170);
    connect(m_feMale, &QPerson::ageChanged, this, &MainWindow::onAgeChanged);

    ui->spinBoxMale->setProperty("sex", true);
    ui->spinBoxFeMale->setProperty("sex", false);
}

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

void MainWindow::onAgeChanged(unsigned age) {
    Q_UNUSED(age)
    QPerson *person = qobject_cast(sender());
    QString name = person->getName();
    unsigned page = person->age();
    QString addr = person->property("addr").toString();
    int icnome = person->property("income").toInt();
    int height = person->property("height").toInt();
    ui->plainTextEdit->appendPlainText(name + ", " + addr +
        QString::asprintf(", 年龄:%d, 收入:%d, 身高:%d", page, icnome, height));
}

void MainWindow::onAdd()
{

}

void MainWindow::onSub()
{

}

void MainWindow::onMetaInfo()
{

}

void MainWindow::on_spinBoxFeMale_valueChanged(int arg1)
{
    Q_UNUSED(arg1)
    QSpinBox *spinBox = qobject_cast(sender());
    if (spinBox->property("sex").toBool()) { // male
        m_male->ageAdd(spinBox->value());
    }
    else { //female
        m_feMale->ageSub(spinBox->value());
    }
}


void MainWindow::on_spinBoxMale_valueChanged(int arg1)
{
    Q_UNUSED(arg1)
    QSpinBox *spinBox = qobject_cast(sender());
    if (spinBox->property("sex").toBool()) { // male
        m_male->ageAdd(spinBox->value());
    }
    else { //female
        m_feMale->ageSub(spinBox->value());
    }
}


void MainWindow::on_pushButtonMetaInfo_clicked()
{
    ui->plainTextEdit->clear();
    ui->plainTextEdit->appendPlainText("=====显示元对象信息=====\n");
    const QMetaObject *meta = m_feMale->metaObject();
    ui->plainTextEdit->appendPlainText(QString("类名: %1\n").arg(meta->className()));
    ui->plainTextEdit->appendPlainText("property:");
    for (int i = meta->propertyOffset(); i < meta->propertyCount(); i++) {
        //QMetaProperty prop = meta;
        QMetaProperty prop = meta->property(i);
        const char *propName = prop.name();
        QString propValue = m_male->property(propName).toString();
        ui->plainTextEdit->appendPlainText(QString("属性名:%1, 属性值:%2").arg(propName).arg(propValue));
    }
    ui->plainTextEdit->appendPlainText("");
    ui->plainTextEdit->appendPlainText("classinfo:");
    for (int i = meta->classInfoOffset(); i < meta->classInfoCount(); i++) {
        QMetaClassInfo classInfo = meta->classInfo(i);
        ui->plainTextEdit->appendPlainText(QString("name: %1, value: %2").
                                           arg(classInfo.name()).arg(classInfo.value()));
    }

}


void MainWindow::on_pushButtonAdd_clicked()
{
     m_male->ageAdd(1);
}


void MainWindow::on_pushButtonSub_clicked()
{
     m_feMale->ageSub(1);
}

qperson.cpp

#include "qperson.h"

QPerson::QPerson(QString name, QObject *parent)
    : QObject{parent}
{
    m_name = name;
}

unsigned QPerson::age()
{
    return m_age;
}

void QPerson::setAge(unsigned age) {
    emit ageChanged(age);
    m_age = age;
}

void QPerson::ageAdd(unsigned age) {
    m_age += age;
    emit ageChanged(m_age);
}

void QPerson::ageSub(unsigned age) {
    m_age -= age;
    emit ageChanged(m_age);
}

QString QPerson::getName() {
    return m_name;
}

 mainwindow.ui



 MainWindow
 
  
   
    0
    0
    507
    357
   
  
  
   MainWindow
  
  
   
    
     
    
    
     
      
       
        
         
          
           男人:
          
         
        
        
         
          
           20
          
         
        
        
         
          
           增大
          
         
        
        
         
          
           女人:
          
         
        
        
         
          
           18
          
         
        
        
         
          
           减小
          
         
        
       
      
      
       
        
         元对象信息
        
       
      
      
       
        
         清空
        
       
      
      
       
        
         Qt::Vertical
        
        
         
          20
          68
         
        
       
      
     
    
   
  
  
   
    
     0
     0
     507
     22
    
   
  
  
 
 
 
  
   pushButtonClear
   clicked()
   plainTextEdit
   clear()
   
    
     438
     73
    
    
     253
     210
    
   
  
 

运行效果如下:
QT系列第2节 QT中元对象系统_第2张图片

QT系列第2节 QT中元对象系统_第3张图片 

 

你可能感兴趣的:(QT,qt)