Qt Meta System调用带参数的构造函数

use*_*416 3 qt qtcore

我知道我可以QMetaType用来创建一个没有参数的对象.

另一种可能的选择是使用QMetaObject和调用newInstance.但我需要得到QMetaObject一些东西.

我试图使用QMetaType::metaObjectForType,但它总是返回空指针(但QMetaType能够创建对象).

QMetaObject const* metaObject = QMetaType::metaObjectForType(id); // return null pointer
   QObject*           object     =   (QObject*)QMetaType::create(id); // create the object
QMetaObject const* metaObject = object->metaObject(); // return not-null pointer
Run Code Online (Sandbox Code Playgroud)

更新:

我认为问题是为什么metaObjectForType不适合我.这个类有注册qRegisterMetaType,还Q_DECLARE_METATYPEQ_OBJECT应用.

hyd*_*yde 5

首先,要将参数传递给方法,除了普通的C++之外,还需要某种反射框架.对于Qt,一个明显的选择是Qt元对象系统QMetaObject,尽管那时你必须派生你的类QObject.之后,您需要做两件事:

1.使构造函数可调用

默认情况下,信号和插槽是可调用的,但是您希望通过元对象系统调用的任何其他方法都需要明确标记为这样.示例myqobject.h:

#ifndef MYQOBJECT_H
#define MYQOBJECT_H
#include <QObject>

class MyQObject : public QObject
{
    Q_OBJECT
public:
    Q_INVOKABLE MyQObject(QObject *parent = 0); // tested with empty constructor in .cpp

};

#endif // MYQOBJECT_H
Run Code Online (Sandbox Code Playgroud)

2.从类名字符串创建自己的映射到 QMetaObject

QMetaTypedoc说:"任何具有公共默认构造函数,公共复制构造函数和公共析构函数的类或结构都可以注册." 这排除了QObject,因为它们不能具有复制构造函数.您需要创建自己的映射,从名称到元对象.这个main.cpp中显示的一个例子:

#include <QCoreApplication>
#include <QtCore>

#include "myqobject.h"

// a global map for mapping strings to QMetaObjects,
// you need header file like this if you want to access it from other .cpp files:
//
// #include <QHash>
// #include <QString>
// class QMetaObject; // forward declaration, enough when only pointer is needed
// extern QHash<QString, const QMetaObject*> metaObjs;
//
QHash<QString, const QMetaObject*> metaObjs;

// optional: create a macro to avoid typing class name twice,
// #c surrounds macro argument with double quotes converting it to string
#define METAOBJS_INSERT(c) (metaObjs.insert(#c, &c::staticMetaObject))

int main()
{
    METAOBJS_INSERT(MyQObject);

    const QMetaObject *meta = metaObjs["MyQObject"];
    qDebug() << "Class name from staticMetaObject: " << meta->className();

    QObject *o = meta->newInstance(); // add constructor arguments as needed
    MyQObject *mo = qobject_cast<MyQObject*>(o);
    if (mo) qDebug() << "Class name from object instance: " << mo->metaObject()->className();
    else qDebug() << "Instance creation failed or created wrong class!";

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果你不想使用QObject,那么你需要提出一些类似的(可能是更轻的,没有单独的编译器步骤)你自己的机制.