C++ Qt/C++;扩展QWidget上的调用函数

C++ Qt/C++;扩展QWidget上的调用函数,c++,qt,C++,Qt,在我的基于Qt的程序中,我有如下层次结构: MyApplication::QMainWindow->QTabWidget->ProjectWidget::QWidget 在MyApplication中,我有一个传统的菜单,其中一个操作是导入,需要调用一个ProjectWidget->importStuff(),由QTabWidget->currentwidt定义 我遇到的问题是,当我使用QTabWidget->currentWidget时,我仅限于QWidget函数的子集,无法调用任何扩展函数。

在我的基于Qt的程序中,我有如下层次结构:

MyApplication::QMainWindow->QTabWidget->ProjectWidget::QWidget

在MyApplication中,我有一个传统的菜单,其中一个操作是导入,需要调用一个ProjectWidget->importStuff(),由QTabWidget->currentwidt定义

我遇到的问题是,当我使用QTabWidget->currentWidget时,我仅限于QWidget函数的子集,无法调用任何扩展函数。我也不知道如何设置一个只会影响单个ProjectWidget的信号/插槽(而不会触发其余的)


我正在考虑向所有ProjectWidget添加一个名为“isCurrent”的属性,然后设置一个调用导入的信号,并检查“isCurrent”状态。如果它是当前小部件,那么它将执行导入功能。但这似乎很复杂,有没有更简单的方法?

您有两个简单的选择

您可以使用静态方法调用任何可调用的方法,只需一个
QObject*
指针和方法名称(以及参数,如果有的话)。要使该方法可调用,可以在子类定义中使用宏,也可以简单地将该方法放入Qt插槽中。然后,您只需要
QObject
指针,就可以(尝试)使用任何参数调用任何方法(如果不存在这样的方法,则会出现错误)

另一种方法是使用,它尝试将QObject子类指针强制转换为另一个,如果无法执行(对象不属于该类),它将返回
nullptr
)。一旦你有了正确的指针类型,只要调用你喜欢的任何方法。它非常像标准C++ +代码> DyrimeCase< /Cuff>,但只适用于QObject子类,因为它使用Qt元对象系统,不依赖于C++ RTTI。 注意:这两种方法是当没有一种单独的、独立于GUI的方式访问小部件时应该使用的。但在你的例子中,这些似乎让事情变得简单了,这是合理的,只要你计划在应用程序的生命周期中保持
QTabWidget


使用invokeMethod方法解决此确切问题时,OP评论中的代码示例:

QMetaObject::invokeMethod(myTabWidget->currentWidget(), "callbackFunction");
这样做的好处是,现在可以有两个本来不相关的
QObject
子类,并且只有同名的可调用方法(不是通用超类方法的重写版本),并且可以调用该方法。不需要在编译时提供类定义,也不需要添加公共基类或引入抽象接口类并使用多重继承。这基本上类似于duck类型:如果
QMetaObject::invokeMethod(ptr,“嘎嘎”)
,那么它就是duck


缺点是没有编译时类型检查,方法名字符串中的简单键入可能会使代码以静默方式失败。因此,当
invokeMethod
在运行时失败时(这是一个bug,还是某些UI状态的正常情况?),思考(并在代码中实现和注释,以及测试)该怎么做是很重要的。但是这也适用于(Qt4语法)
QObject::connect
,因为很多Qt程序员都经历了艰难的过程,当slot因为输入错误而没有被调用时:-)。

您有两个简单的选择

您可以使用静态方法调用任何可调用的方法,只需一个
QObject*
指针和方法名称(以及参数,如果有的话)。要使该方法可调用,可以在子类定义中使用宏,也可以简单地将该方法放入Qt插槽中。然后,您只需要
QObject
指针,就可以(尝试)使用任何参数调用任何方法(如果不存在这样的方法,则会出现错误)

另一种方法是使用,它尝试将QObject子类指针强制转换为另一个,如果无法执行(对象不属于该类),它将返回
nullptr
)。一旦你有了正确的指针类型,只要调用你喜欢的任何方法。它非常像标准C++ +代码> DyrimeCase< /Cuff>,但只适用于QObject子类,因为它使用Qt元对象系统,不依赖于C++ RTTI。 注意:这两种方法是当没有一种单独的、独立于GUI的方式访问小部件时应该使用的。但在你的例子中,这些似乎让事情变得简单了,这是合理的,只要你计划在应用程序的生命周期中保持
QTabWidget


使用invokeMethod方法解决此确切问题时,OP评论中的代码示例:

QMetaObject::invokeMethod(myTabWidget->currentWidget(), "callbackFunction");
这样做的好处是,现在可以有两个本来不相关的
QObject
子类,并且只有同名的可调用方法(不是通用超类方法的重写版本),并且可以调用该方法。不需要在编译时提供类定义,也不需要添加公共基类或引入抽象接口类并使用多重继承。这基本上类似于duck类型:如果
QMetaObject::invokeMethod(ptr,“嘎嘎”)
,那么它就是duck


缺点是没有编译时类型检查,方法名字符串中的简单键入可能会使代码以静默方式失败。因此,当
invokeMethod
在运行时失败时(这是一个bug,还是某些UI状态的正常情况?),思考(并在代码中实现和注释,以及测试)该怎么做是很重要的。但这也适用于(Qt4语法)
QObject::connect
,因为许多Qt程序员都经历了艰难的过程,当时插槽因为输入错误而没有被调用:-)。

(很抱歉,缺少指向Qt文档的链接,从tablet on the road上编写,明天将添加回答的链接…)感谢海德,我找到了合适的文档。在这个例子中,我喜欢方法#2——我确实同意传递指针的是I