[Interest] How to create QObject-derived class instance from class name

André Somers andre at familiesomers.nl
Tue Mar 1 17:51:52 CET 2016



Op 01/03/2016 om 17:21 schreef Thiago Macieira:
> On terça-feira, 1 de março de 2016 17:06:49 PST André Somers wrote:
>>> The meta *object* system has no registration.
>>>
>>> The meta *type* system requires that the registered type be default-
>>> constructible and copyable, but QObject is not copyable. Therefore,
>>> QObject- derived classes cannot be registered with the meta type system.
>> Am I completely misinterpretting the documentation then?
>> http://doc.qt.io/qt-5/qmetatype.html#metaObject
>>
>> If I read that correctly, you can register a
>> pointer-to-a-QObject-derived-class-instance and use that. So, indeed,
>> you do not register the type, but the type*. And that has no problems
>> with being default constructed or copied.
> Correct. You can't register a QObject class with the meta type system, but you
> can register a pointer to a QObject class. The problem is that
> QMetaType::create() will then create a pointer, not the object.
Of course. But... Again, if I read it correctly, you *can* then get the 
QMetaObject from QMetaType, and using that, you can create an actual 
instance.

Just tested this trivial example:

//main.cpp
int main(int argc, char *argv[])
{
     qRegisterMetaType<TestClass*>(); //this could be elsewhere of course

     QCoreApplication a(argc, argv);

     auto tId = QMetaType::type("TestClass*"); //just using the class 
name with an *
     auto metaObject = QMetaType::metaObjectForType(tId);
     QObject* instance = metaObject->newInstance();

     return a.exec();
     delete instance;
}

//testclass.h
class TestClass: public QObject
{
     Q_OBJECT

public:
     Q_INVOKABLE TestClass();
};

Q_DECLARE_METATYPE(TestClass*)

//testclass.cpp
TestClass::TestClass()
{
     qDebug() << "TestClass instance created";
}

Which prints out "TestClass instance created" on the console. My 
conclusion is that it works, and that you _can_ create a QObject derived 
instance with just the class name.

Again: I am not claiming that abusing this to skip defining a factory is 
a good idea. Just that it is possible.


André




More information about the Interest mailing list