我在Qt上是一个新奇的问题,QSharedPointer
在信号中传递了一些问题。我正在使用两个线程(UI和一个worker)。工作人员使用包含自定义QObject的QSharedPointer的信号向UI发送信号:
class MyObject : QObject {...}
class Window : public QWidget {
Q_OBJECT
public slots:
void onFound(QSharedPointer<MyObject>);
}
class Worker : public QObject {
Q_OBJECT
public signals:
void found(QSharedPointer<MyObject>);
}
我使用found
将工作者onFound
与windows Qt::QueuedConnection
连接起来,因为它们存在于不同的线程中,因此通信必须是异步的。
现在我观察到以下行为,当我传递最后一个引用我的对象的qazxsw poi时:
QSharedPointer
的指针并激活它。这不是我的预期 - 虽然这是合理的。 QSharedPointer一般是通过这种方式传递信号吗?如果是这样的话,在排队的时候是否有一种机制来保持参考?
我考虑了下面的解决方案,但我对它们都没有完全没问题:
void*
然后我仍然必须以某种方式切换线程(与以前相同的情况)Qt::DirectConnection
参数的新信号/槽,用于传递要在目标线程中执行的lambda函数并捕获我的共享指针的副本。 (这是我目前的解决方案,但它不是优雅的,不是吗?)您还有其他建议或想法吗?
信号返回不会破坏相应的对象。 std::function
调用复制共享指针。这是QMetaObject::activate
信号的实现:
send
您可能正在经历一场竞赛:当发出信号的线程恢复执行时,目标线程已经收到了该对象。因此,它在发射线程中显示对象消失了 - 因为到那时,它就是。然而,目标对象接收实例就好了。它工作正常。
下面的示例说明它适用于单线程和多线程情况,然后通过确保目标线程始终赢得竞争来重现您的问题:
// SIGNAL 0
void IO::send(const QSharedPointer<Unique> & _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}