你有两个简单的选择
您可以使用QMetaObject::invokeMethod
静态方法来调用任何可调用的方法,您只需要一个QObject*
指针和方法名称(以及参数,如果有的话)。要使方法可调用,Q_INVOKABLE
请在子类定义中使用宏,或者简单地将方法放入 Qt 槽中。然后你只需要QObject
指针,并且可以(尝试)使用任何参数调用任何方法(如果不存在这样的方法,则会出错)。
另一种方法是使用qobject_cast<>()
,它尝试将QObject子类指针转换为另一个,nullptr
如果无法完成(对象不属于该类),将返回 。一旦你有了正确的指针类型,就可以调用你喜欢的任何方法。它很像标准 C++ dynamic_cast<>
,但仅适用于 QObject 子类,因为它使用 Qt 元对象系统并且不依赖于 C++ RTTI。
注意:当没有很好的方法来使用单独的、独立于 GUI 的方法来访问小部件时,您应该使用这两种方法。但是在您的情况下,这些似乎使事情变得如此简单,这是合理的,只要您计划QTabWidget
在应用程序的整个生命周期内保留它。
OP评论中的代码示例,关于使用invokeMethod
解决这个确切问题的方法:
QMetaObject::invokeMethod(myTabWidget->currentWidget(), "callbackFunction");
这样做的好处是,现在可以拥有两个QObject
原本不相关的子类,并且只有具有相同名称的可调用方法(不是通用超类方法的覆盖版本),并且可以调用该方法。编译时不需要类定义可用,不需要添加通用基类或引入抽象接口类和使用多重继承。这基本上就像鸭子打字:如果QMetaObject::invokeMethod(ptr, "quack")
,那么它是鸭子。
缺点是没有编译时类型检查,方法名称字符串中的简单拼写错误会使代码静默失败。因此,重要的是要思考(并在代码中实现和注释,并测试)当invokeMethod
运行时失败时该怎么做(是错误,还是某些 UI 状态的正常情况?)。但这也适用于(Qt4 语法)QObject::connect
,因为许多 Qt 程序员已经学会了艰难的方法,当插槽由于拼写错误而没有被调用时 :-)。