Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt/C++: What's the best way to call a method asynchronously in Qt event loop without having to write its name as string?

The normal way is with invokeMethod:

QMetaObject::invokeMethod(this, "methodName", Qt::QueuedConnection);

which works fine, except that I don't want to write methods in strings. Like ever. Why? Because this is a refactoring nightmare. Imagine having to change a method name for some reason. The software will malfunction and I'll have to notice in stderr that the method doesn't exist.

My solution?

I use QTimer. Like this:

QTimer::singleShot(0, this, &ClassName::methodName);

which seems to work fine. What I like about this is that you can replace the &ClassName::methodName part with a lambda/bind and it'll still be bound to the correct object (in case I need to use it with QThread) with the expected variable referencing we understand in standard C++:

QTimer::singleShot(0, threadObject, [this, param1, &param2](){ this->methodName(param1, param2); });

Better solutions exist?

But... I'm hoping there's a better way to do this because someone reading my code will not understand why I'm using a QTimer here... so I gotta comment everything.

Is there a better way to do this that's compatible with versions of Qt down to 5.9 or 5.7? What's the best solution you know?

like image 981
The Quantum Physicist Avatar asked Nov 07 '22 03:11

The Quantum Physicist


1 Answers

Since Qt 5.10 there are functor-based overloads of QMetaObject::invokeMethod.

This means that you can ditch the string-based approach and use the modern way of calling methods with invokeMethod too.

like image 111
Ruslan Avatar answered Nov 10 '22 01:11

Ruslan