首页 > 其他分享 >Qt通过类名动态创建对象(反射机制)

Qt通过类名动态创建对象(反射机制)

时间:2022-09-23 16:57:47浏览次数:72  
标签:return Qt parent 创建对象 MyClass include MainWindow 类名 name

反射机制

C#中支持反射机制而C++中不支持,基于QT的元对象系统,之前使用QT的反射机制创建属性表,现学习使用QT通过类名动态创建对象。

反射机制的优点:

  • 1、反射提高了程序的灵活性和扩展性。
  • 2、降低耦合性,提高自适应能力。
  • 3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。

2 结果现象

输入MyClass类名,可以动态创建对象,访问类中的属性方法。

3 程序代码

mainwindow.h
  1 #ifndef MAINWINDOW_H
  2 #define MAINWINDOW_H
  3  
  4 #include <QMainWindow>
  5 #include <QByteArray>
  6 #include <QMetaObject>
  7 #include <QHash>
  8 #include <QLineEdit>
  9 #include <QMetaProperty>
 10 #include <QPushButton>
 11 #include <QDebug>
 12 #pragma execution_character_set("utf-8")
 13  
 14 QT_BEGIN_NAMESPACE
 15 namespace Ui { class MainWindow; }
 16 QT_END_NAMESPACE
 17 class MyClass;
 18  
 19 class MyClass : public QWidget
 20 {
 21     Q_OBJECT
 22 public:
 23  
 24     MyClass(QWidget *parent = nullptr);
 25     Q_PROPERTY(uint uCrc READ uCrc WRITE setuCrc)
 26     Q_PROPERTY(uint StructLen READ StructLen WRITE setStructLen)
 27     ~MyClass();
 28     int num;
 29     void pCout();
 30  
 31     uint uCrc() const
 32     {
 33         qDebug()<<"uCrc"<<m_uCrc;
 34         return m_uCrc;
 35     }
 36     uint StructLen() const
 37     {
 38         return m_StructLen;
 39     }
 40  
 41 public slots:
 42     void setuCrc(uint uCrc)
 43     {
 44         qDebug()<<"setuCrc"<<uCrc<<"success!!!!!!!!!!!!!!!";
 45         m_uCrc = uCrc;
 46     }
 47     void setStructLen(uint StructLen)
 48     {
 49         m_StructLen = StructLen;
 50     }
 51  
 52 private:
 53     uint m_uCrc;
 54     uint m_StructLen;
 55 };
 56  
 57 class MainWindow : public QMainWindow
 58 {
 59     Q_OBJECT
 60  
 61 public:
 62     MainWindow(QWidget *parent = nullptr);
 63     ~MainWindow();
 64  
 65     QStringList m_Register;
 66  
 67     void create(QString name);
 68  
 69 private slots:
 70     void on_lineEdit_editingFinished();
 71  
 72 private:
 73     Ui::MainWindow *ui;
 74 };
 75  
 76 #ifndef REFLECT_H
 77 #define REFLECT_H
 78 template<typename L>
 79 class Reflect
 80 {
 81 public:
 82  
 83     template<typename T>
 84     static void registerClass(QString name)
 85     {
 86         constructors().insert( name.toLatin1(), &constructorHelper<T> );
 87     }
 88  
 89     static QObject* newInstance( const QByteArray& className, L* parent = nullptr )
 90     {
 91         Constructor constructor = constructors().value( className );
 92         if ( constructor == nullptr )
 93             return nullptr;
 94         return (*constructor)( parent );
 95     }
 96  
 97 private:
 98     typedef QObject* (*Constructor)( L* parent );
 99  
100     template<typename T>
101     static QObject* constructorHelper( L* parent )
102     {
103         return new T( parent );
104     }
105  
106     static QHash<QByteArray, Constructor>& constructors()
107     {
108         static QHash<QByteArray, Constructor> instance;
109         return instance;
110     }
111 };
112  
113 #endif // REFLECT_H
114 #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    Reflect<QWidget>::registerClass<QLineEdit>("QLineEdit");
    Reflect<QWidget>::registerClass<QPushButton>("QPushButton");
    Reflect<QWidget>::registerClass<MyClass>("MyClass");
    m_Register.append("QLineEdit");
    m_Register.append("QPushButton");
    m_Register.append("MyClass");
 
}
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::create(QString name)
{
    qDebug()<<"start";
 
    QObject *object = Reflect<QWidget>::newInstance(name.toUtf8());
 
    const QMetaObject *p = object->metaObject();
    //打印属性与方法名
    for(int i = 0;i < p->methodCount();i++)
    {
        qDebug()<<p->method(i).name()<<"~~~~~~method~~~~~~";
    }
    for(int i = 0;i < p->propertyCount();i++)
    {
        qDebug()<<p->property(i).name()<<"----property---";
    }
 
    /**
     * @brief 动态创建名称为 name 的类
     * 该程序测试的类名 name = MyClass
     * 之后进行测试打印 MyClass类 中的uCrc
     * 成功打印setuCrc 12 success!!!!!!!!!!!!!!!
     *
     */
    qDebug()<<"===============================";
 
    QMetaProperty pe = p->property(p->indexOfProperty("uCrc"));
    pe.write(object,12);
 
    qDebug()<<"end";
}
MyClass::MyClass(QWidget *parent)
{
    parent = nullptr;
}
 
MyClass::~MyClass()
{
    delete this;
}
 
void MyClass::pCout()
{
    qDebug()<<"pCout";
}
 
 
void MainWindow::on_lineEdit_editingFinished()
{
    QString str = ui->lineEdit->text();
    if(!m_Register.contains(str))
        return ;
    this->create(str);
}

 main.cpp

#include "mainwindow.h"
#include <QApplication>
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
 
    MainWindow w;
    w.show();
 
    return a.exec();
}

 

标签:return,Qt,parent,创建对象,MyClass,include,MainWindow,类名,name
From: https://www.cnblogs.com/qter/p/16723279.html

相关文章