zoukankan      html  css  js  c++  java
  • Qt moc元对象编译器的原理和场景(反射)

    Qt Meta-Object Compiler (moc)

    元对象编译器,能够实现运行时类型识别。可以用在需要用到反射机制的情况下,qml使用c++的类和方法就是使用了这个特性,通过Q_PROPERTY在类内注册属性;

    使用Qt的元对象系统的方法:

    1. 类要继承自QObject

    2. 在类申明开始写上Q_OBJECT宏,Q_OBJECT宏的展开为:

       static const QMetaObject staticMetaObject; 
       virtual const QMetaObject *metaObject() const; 
       virtual void *qt_metacast(const char *); 
       virtual int qt_metacall(QMetaObject::Call, int, void **); 
       Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); 
      

    moc识别到这个宏之后会编译出moc_youclass.cpp文件,里面有这几个方法和函数的定义和使用;

    myclass.h

    #ifndef MYCLASS_H
    #define MYCLASS_H
    
    #include <QObject>
    
    class MyClass : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
        Q_PROPERTY(int size READ size WRITE setSize NOTIFY sizeChanged)
    public:
        explicit MyClass(QObject *parent = nullptr);
    
        Q_INVOKABLE  void PrintSelf();
        QString name() const
        {
            return m_name;
        }
    
        size_t size() const
        {
            return m_size;
        }
    
    signals:
    
        void nameChanged(QString name);
    
        void sizeChanged(size_t size);
    
    public slots:
    
    void setName(QString name)
    {
        if (m_name == name)
            return;
    
        m_name = name;
        emit nameChanged(m_name);
    }
    
    void setSize(size_t size)
    {
        if (m_size == size)
            return;
    
        m_size = size;
        emit sizeChanged(m_size);
    }
    
    private:
        QString m_name;
        int m_size;
    };
    
    #endif // MYCLASS_H
    
    

    main.cpp

    #include <QCoreApplication>
    #include <iostream>
    #include <QVariant>
    #include <QDebug>
    #include <QMetaMethod>
    #include "myclass.h"
    using namespace std;
    
    void test()
    {
        cout << "-------test property-----------" << "
    ";
        MyClass newObj;
        newObj.setProperty("type", "fuck");
        newObj.setProperty("Member1", 66);
        cout << newObj.property( "Member1" ).toString().toStdString() << "
    ";
        const QMetaObject* mobj = newObj.metaObject();
        qDebug() << "obj name = " << mobj->className();
    
        int propertyCount = mobj->propertyCount();
        for(int n = 0; n < propertyCount; ++n)
        {
            qDebug() << "property index : " << n;
            QMetaProperty property = mobj->property(n);
            qDebug() << "property : " << property.name();
            qDebug() << "property value : " << property.read(&newObj);
        }
    
        int methodCount = mobj->methodCount();
        for(int n = 0; n < methodCount; ++n)
        {
            qDebug() << "method index : " << n;
            QMetaMethod method = mobj->method(n);
            qDebug() << "method name : " << method.name();
            method.invoke(&newObj);
        }
    
     QMetaObject::invokeMethod( &newObj, "PrintSelf", Qt::DirectConnection);
    
        MyClass* myClass = dynamic_cast<MyClass*>(mobj->newInstance());
        cout << "--------end----------" << "
    ";
    }
    
    int main(int argc, char *argv[])
    {
        test();
        QCoreApplication a(argc, argv);
    
        return a.exec();
    }
    
    
  • 相关阅读:
    2.搭建第一个http服务:三层架构
    1.基础入门
    MyISAM和InnoDB索引区别
    分区
    事务的四大特性
    事务
    String
    自己写native方法
    序列化和反序列化
    反射
  • 原文地址:https://www.cnblogs.com/wzxNote/p/14139537.html
Copyright © 2011-2022 走看看