我知道我可以使用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
更新
我认为问题是为什么metaObjectForType
对我不起作用。
该课程已在qRegisterMetaType
注册,同时也会Q_DECLARE_METATYPE
,Q_OBJECT
已应用。
答案 0 :(得分:5)
首先,要将参数传递给方法,除了普通的C ++之外,还需要某种反射框架。对于Qt,一个明显的选择是Qt元对象系统,它是QMetaObject
,但是你必须为QObject
派生你的类。之后,您需要做两件事:
默认情况下,信号和插槽是可调用的,但是您想要通过元对象系统调用的任何其他方法都需要明确标记。示例 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
QMetaObject
QMetaType
doc说:“任何具有公共默认构造函数,公共复制构造函数和公共析构函数的类或结构都可以注册。”这排除了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;
}
如果您不想使用QObject
,那么您需要提出自己的一些类似(可能更轻,没有单独的编译器步骤)机制。
答案 1 :(得分:0)
我遇到了同样的问题。 解决方案分为两个步骤:
还要确保您的类派生自QObject并且其中包含Q_OBJECT宏。
class A : public QObject
{
Q_OBJECT
public:
A(const A&) {}; // dummy copy contructor that do nothing to disable error message
Q_INVOKABLE A(int test_value = 99999) : TestValue(test_value) {};
int TestValue;
};
Q_DECLARE_METATYPE(A);
int main(int argc, char *argv[])
{
qRegisterMetaType<A>(); //you do not need this
qRegisterMetaType<A*>();//the real registration
int type_id_for_A = QMetaType::type("A"); // valid type id (in my case = 403)
const QMetaObject *meta_object_for_A = QMetaType::metaObjectForType(type_id_for_A); // returns NULL
int type_id_for_A_ptr = QMetaType::type("A*"); // valid type id (in my case = 404)
const QMetaObject *meta_object_for_A_tr = QMetaType::metaObjectForType(type_id_for_A_ptr); // returns NOT NULL
A* A_obj= dynamic_cast<A*>(meta_object_for_A_tr->newInstance(Q_ARG(int, 12345)));
int test_value = A_obj->TestValue; // returns 12345, not 99999
}