Qt: 在其他线程中向事件循环添加函数调用

3
我遇到了一个问题,目前找不到一种优雅的解决方式。 情况是这样的:我有一个回调函数,它从我的应用程序外部被调用。回调函数必须更新一些GUI对象。由于我不能从另一个线程中调用(例如)repaint(),所以我必须找到一种方法将函数调用添加到主事件循环中,以便任务在某个时间得到执行。
一种可能的方法是使用以下内容:
QMetaObject::invokeMethod(object, "functionName", Qt::QueuedConnection, Q_ARG(float, value)); 

然而,这只是让我收到了“没有这样的方法”Object::functionName”的响应。(显然是假的!)
我还阅读过有关将信号连接到插槽并将连接类型设置为Qt::QueuedConnection以从事件循环调用插槽的内容。但是,使用QOjbect.connect()不起作用,因为我不知道信号需要获取的对象。好的方法应该是:
QObject.emit(object, SIGNAL(function(flaot)), arg);

通常情况下,QMetaObject::invokeMethod 运行良好。它也不会说谎,如果您在调用中有拼写错误,它将失败(因为它在运行时被评估 - 没有编译器检查函数是否存在),并输出该消息。检查您的调用,它应该可以工作。 - Zaiborg
1个回答

3

QMetaObject::invokeMethod通常是您在这种情况下应该使用的方法。请确保:

  • object 是一个QObject子类,在顶部有Q_OBJECT宏定义。
  • functionName 要么在slots节声明,要么有Q_INVOKABLE宏定义。

嗨,将其声明为插槽有所帮助。不知何故错过了这一点。谢谢!没有更“快”的方法吗?应用程序非常注重性能(实时音频等),我希望尽可能节省CPU时间。 :) - ruhig brauner
1
我不知道有没有,据我所知,在跨线程中发布自定义QEvent或使用0ms QBasicTimer是不可能的。InvokeMethod的开销很大,因此我过去一直依赖于将调用批处理为尽可能少的消息,在其中使用QMutex或QSemaphore保护所有累积的数据进行处理。 - jturcotte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接