我知道我可以使用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
。
发布于 2013-10-21 20:04:43
首先,要将参数传递给方法,您需要某种超出普通C++的反射框架。对于Qt,obivous的选择是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
2.创建从类名字符串到QMetaObject
的映射
QMetaType
文档说:“任何具有公共默认构造函数、公共副本构造函数和公共析构函数的类或结构都可以注册。”这就排除了QObject,因为它们不能有复制构造函数。您需要创建从name到meta对象的映射。本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
,那么您需要想出一些类似的机制(可能更轻,而且没有单独的编译步骤)。
发布于 2014-01-18 10:14:11
我也有同样的问题。解决办法分两个步骤:
还请确保您的类是从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
}
https://stackoverflow.com/questions/19503583
复制相似问题