来自主线程的信号没有到达第二线程qt5的插槽
Signal from Main Thread not reaching slot in Second Thread Qt 5
我正在编写一个程序,每REFRESH_RATE
毫秒从相机捕获一个图像,将其发送给一些计算算法。我决定使用QThread
来计时这个算法的启动时间,但是这个算法是在主线程上运行的,因为我需要在此之前创建的对象。不管怎样,这很有效。当我试图关闭第二个线程时,问题就开始了……代码如下:
照相机:
class Camera : public QMainWindow
{
Q_OBJECT
public:
Camera(QWidget *parent = 0){
AlgoQThread = new QThread;
myAlgoThreadWorker = new AlgoThreadWorker( (Camera *) this );
myAlgoThreadWorker->moveToThread(AlgoQThread);
//Launch The thread
connect(AlgoQThread, SIGNAL(started()), myAlgoThreadWorker, SLOT(process()));
connect(myAlgoThreadWorker, SIGNAL(finished()), AlgoQThread, SLOT(quit()));
// The line meant to stop the thread at next loop
connect(this, SIGNAL(stopAlgoThread()), myAlgoThreadWorker, SLOT(stopThread()));
connect(myAlgoThreadWorker, SIGNAL(finished()), myAlgoThreadWorker, SLOT(deleteLater()));
connect(AlgoQThread, SIGNAL(finished()), AlgoQThread, SLOT(deleteLater()));
AlgoQThread->start();
}
private slots:
void errorString(QString error);
//This function is triggered by a signal sent by the method called in AlgoThreadWoker::process()
void some_algorithm(){
...
emit stopAlgoThread();
}
signals:
void stopAlgoThread();
private:
QThread * AlgoQThread;
AlgoThreadWorker * myAlgoThreadWorker;
};
algoThreadWorker:
class AlgoThreadWorker : public QObject
{
Q_OBJECT
public:
AlgoThreadWorker(Camera * context){
parentCamera = context;
}
Camera* parentCamera;
public slots:
void process(){
while(1){
QMutexLocker locker(&m_mutex);
if (t_stop) break;
parentCamera->isCapturingImage = true;
//This triggers the some_algorithm() using a signal sent by imageCapture from main Thread
parentCamera->imageCapture->capture();
//Wait REFRESH_RATE millisecondes
Sleep(REFRESH_RATE);
}
//Ends the thread
emit finished();
}
private slots:
void stopThread(){
QMutexLocker locker(&m_mutex);
t_stop = true;
};
signals:
void finished();
void error(QString);
private:
bool t_stop;
QMutex m_mutex;
};
好吧,正如你所预见的,它不起作用。我可以启动some_algorithm()
没有问题,但我不能结束线程。stopThread()
插槽甚至没有启动,我已经测试过了。
由于您在while循环中忙于等待,因此事件循环永远没有机会处理接收到的信号。
qApp->processEvents()
将控制权交给事件循环,以便处理等待的作业。
注意,通常你不需要自己调用它,Qt会为你做。在你的情况下,这是必要的,因为你有一个无限循环,阻止Qt做它的工作。
解决方案:
void process(){
while(1){
qApp->processEvents();
^^^^^^^^^^^^^^^^^^^^^^
.....
}
//Ends the thread
emit finished();
}
stopThread()
是私有的,因此只能从AlgoThreadWorker
访问。
Qt的事件循环已经提供了安全的跨线程槽调用和事件传递。你的错误主要是与错误地重新实现Qt已经提供:
-
事情已经是线程安全的了。删除互斥锁
-
thread->quit()
工作,并将退出在给定线程中运行的事件循环。在QThread
中,线程将结束, -
不要让你的代码无缘无故不可移植(
Sleep
是特定于windows的)。如果您希望周期性地做一些事情,只需运行一个计时器(QBasicTimer
或QTimer
)。
这个答案提供了一个完整的例子
相关文章:
- 通过插槽和信号在不同线程中的两个qt对象之间进行通信
- Qt信号和插槽如果从QRunnable或其他线程调用,则不起作用
- boost信号和插槽在不同的线程中不工作(使用boost::asio::io_service)
- Qt5 跨线程信号和插槽
- 信号/插槽多线程 Qt
- Qt-使用信号和具有不同线程的插槽
- 一个类中的QT信号/插槽,但从不同的线程发出
- 我有 12 个 CPU,1 个插槽,每个插槽 6 个内核,每个内核 2 个线程 - 这些信息如何对应于 MPI 和 Op
- 从第二个线程调用Qt信号有效 - >对连接的插槽没有影响
- 为什么即使在使用 Qt::D irectConnection 之后,接收器的线程中仍会调用插槽?如何确保在另一个线程中调用它?
- 将工作线程信号与主窗口插槽 (Qt5) 连接时出错
- QT插槽未在多线程DLL中执行
- QT对象::连接:没有此类插槽信号到线程插槽
- 如何将信号从线程连接到插槽
- 交叉线程信号插槽,如何发送字符*
- worker是否可以在Qt中使用信号/插槽连接停止自己的线程?
- 如何在 Windows 上的线程退出时释放 TLS 插槽中的对象
- 使用QtConcurrent::run连接单独线程上的信号/插槽
- 将只有插槽的QGLWidget移动到不同的线程
- 事件队列是否与用于跨线程信号/槽(在Qt中)的队列相同?