0

My Qt5/C++ program creates a method name (string) on the fly and then if the method is invokable will call it (using invokemethod). And if not invokable/does not exist, then it will no attempt to invoke it. My methods would be defined like this:

Q_INVOKABLE void m1();
void m2();
Q_INVOKABLE void m3();

So m1 and m3 would be directly invokable using "invokemethod". But m2 would not. Since my code will determine on the fly which method to invoke (creating a string with the method name), I need to test if a method is invokable at runtime. How can I do that? I want something like:

bool invokable = QMetaObject::isInvokable(classptr,"m2");

would return false,

bool invokable = QMetaObject::isInvokable(classptr,"m1");

would return true,

bool invokable = QMetaObject::isInvokable(classptr,"nosuchmethod");

would return false. I found a method called:

int QMetaObject::indexOfMethod(const char *method) const

But it doesn't seem to care about the class, just the method name. How can that be usefull, some class A might have an "M1" defined will class B might not have an "M1" method defined.

TSG
  • 4,242
  • 9
  • 61
  • 121
  • 2
    `QMetaObject::indexOfMethod` perhaps. – Igor Tandetnik Jan 26 '23 at 13:47
  • Please note I expanded the question to cover indexOfMethod - still not clear how that could be used if multiple classes have/don't have identically named methods. Can you answer with an example. – TSG Jan 26 '23 at 13:50
  • @TSG `indexOfMethod()` is not `static` so no need to specify the class since you already call the function for an actual instance. – Fareanor Jan 26 '23 at 13:51
  • `indexOfMethod` is a non-static member, it acts on a particular instance of `QMetaObject` describing a particular class. – Igor Tandetnik Jan 26 '23 at 13:51
  • I'm still not clear how to call it. Do I have to make a QMetaObject instance first? How do I pass my class ptr? Does my class have to inherit from QMetaObject? Still struggling to connect the dots. Could you answer with sample code? – TSG Jan 26 '23 at 14:00
  • @TSG For each `QObject`, a `QMetaObject` is created and accessible through `QObject::metaObject()` [as you can read it here in the documentation](https://doc.qt.io/qt-6/qmetaobject.html#details:~:text=A%20single%20QMetaObject%20instance%20is%20created%20for%20each%20QObject%20subclass%20that%20is%20used%20in%20an%20application%2C%20and%20this%20instance%20stores%20all%20the%20meta%2Dinformation%20for%20the%20QObject%20subclass.%20This%20object%20is%20available%20as%20QObject%3A%3AmetaObject().). – Fareanor Jan 26 '23 at 14:17

1 Answers1

3

AFAIK, there is no such function available but you can easily write your own by taking advantage of QMetaObject::indexOfMethod() (as proposed by @Igor Tandetnik).

It returns -1 if the method is not found (it returns its index otherwise).

Something like:

bool isInvokable(QObject * obj, const char * method)
{
    return obj->metaObject()->indexOfMethod(method) != -1;
}
Fareanor
  • 5,900
  • 2
  • 11
  • 37