我想在自己的线程中调用object的槽。换句话说,将槽处理放入接收器的线程队列中。
据我所知,可以使用
完成QMetaObject::invokeMethod(objPtr, "someMethod", Qt:: QueuedConnection);
但至于我,这种方式是不安全的。因为没有关于这种名称的方法的存在的任何编译时检查。如果出现错误,则错误仅在运行时发生,并且仅在日志中发生。
另一种方法是创建像
这样的虚拟信号void callObj();
并将此虚拟信号连接到插槽
connect(this, &Obj1::callObj, objPtr, &Obj2::someMethod, Qt:: QueuedConnection);
但这种方式看起来非常糟糕。
有没有办法做到这一点?
提前感谢您的帮助。
答案 0 :(得分:2)
如果您定义了要调用的接口,则可以使用单个镜头QTimer
并暂停0ms:
QTimer::singleShot(0, obj, &Class::slot);
你也可以用lambda
来调用它QTimer::singleShot(0, obj, [obj]{ obj->slot(42); } );
这种方法要求目标线程运行自己的事件循环(即QThread::exec()
),但由于你想在其线程中运行插槽,我认为这就是你想要的。
答案 1 :(得分:0)
这不是不安全的 - 如果方法不存在,invokeMethod()
将返回false
,不会发生任何不良情况。检查返回值以确定进一步的操作过程。它不会崩溃或类似的东西。
您可以使用qobject_cast
来确保您的指针属于正确的类型,这应该足以验证它是否具有特定方法。除此之外,请注意不要输错,也不要使用未经测试的代码。
另外,考虑除了隐式对象线程关联之外,还有其他几种方法可以利用多线程。
我不会把虚拟信号的方法称为“非常糟糕” - 它只是一个黑客攻击,而且攻击与Qt齐头并进,它与框架一样巨大,远非完全无法实现。