Qt函数调用问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt函数调用问题相关的知识,希望对你有一定的参考价值。

一个Mainwidget类,一个作图类PaintArea,一个线程类WorkThread。

文件mainwidget.cpp中
PaintArea *pas; //pas是全局变量
在MainWidget中

...
pas = new PaintArea;
...

另外文件workthread.cpp中
extern PaintArea *pas;
void WorkThread::run()

pas->hide();


pas->hide(); 这样使用编译出错!

小妹初学Qt,不明白这是为什么?请大侠指点!

参考技术A 正确的做法就是在 mainwindow.cpp 里面去包含 func.h
编译会报错: 无法找到函数calculate(); 说明编译器没有找到 calculate函数的实现
这里就要分成两种情况..
一种就是编译器没有找到 func.cpp 这个文件,你可以尝试把 func.cpp 加入到工程里面或把func.cpp文件所在路径(完整路径)加入到Qt pro 文件中
DEPENDPATH = 你的路径..
另一种就是你的 calculate() 函数格式写错了.所以找到了func.cpp文件也找不到 calculate 函数.
因为 C和C++的编译规则不一样... 试试在extern "C"
func.h

请采纳。追问

??

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

【中文标题】扩展 QWidget 上的 Qt/C++ 调用函数【英文标题】:Qt/C++ call function on extended QWidget 【发布时间】:2013-11-05 18:14:36 【问题描述】:

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

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

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

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

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

【问题讨论】:

【参考方案1】:

你有两个简单的选择

您可以使用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 状态的正常情况?),思考(并在代码中实现和注释,并测试)是很重要的。但这也适用于QObject::connect 的(Qt4 语法),因为许多 Qt 程序员已经学会了艰难的方法,当插槽由于拼写错误而没有被调用时 :-)。

【讨论】:

(抱歉缺少 Qt 文档的链接,在路上用平板电脑写,明天会添加链接来回答......) 感谢 Hyde,我设法找到了合适的文档。在这种情况下,我喜欢方法#2——我同意传递指针是理想的,但在这种情况下,强制对特定类的更多依赖似乎是不可取的。主窗口中只有几个 QActions 需要与项目对话,所以即使它不那么优雅,我也愿意接受一个“丑陋”的组件来支持整体更清洁的设计。 ++ 很好的建议。 (刚刚收到编辑/更新)完美运行,我将用解决方案为未来的读者更新我的问题。 @Kver 只接受答案,在 Stack Overflow,您不应该编辑以添加问题的答案。 好的。但是对于前面提到的未来读者,这是解决方案最终导致的代码行:QMetaObject::invokeMethod(myTabWidget->currentWidget(), "callbackFunction");

以上是关于Qt函数调用问题的主要内容,如果未能解决你的问题,请参考以下文章

Qt能调用C语言函数吗

QT出现重复调用SLOT函数

Qt invokeMethod 异步调用

Qt5 在 Python 脚本中调用函数

如何从 Qt/C++ 的子函数中调用非静态父函数?

如何使用 QT/python 从 Javascript 调用 C++ 函数?