Qt Meta-Object Compiler (moc)
元对象编译器,能够实现运行时类型识别。可以用在需要用到反射机制的情况下,qml使用c++的类和方法就是使用了这个特性,通过Q_PROPERTY在类内注册属性;
使用Qt的元对象系统的方法:
-
类要继承自QObject
-
在类申明开始写上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();
}