所以我有一个有2个插槽的工作类:StartWork()和StopWork(),StartWork()运行一个无限循环(它只是读取和读取摄像头输入不停),StopWork()方法只是设置一个bool变量为false(因此StartWork()内的循环停止).
根据QThread文档,现在使用它们的最佳方法不是通过子类化,而是通过将工作者移动到线程中,这就是我所做的.问题是,来自线程的started()信号被调用,但是完成的()信号永远不会被调用.
工人类槽:
void StartWork(){running = true; 而(跑步){做工; }}
void StopWork(){running = false; }
QThread初始化和信号/插槽连接:
thread = new QThread();
worker = new Worker();
worker.moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), worker, SLOT(StartWork()));
QObject::connect(thread, SIGNAL(finished()), worker, SLOT(StopWork()));
Run Code Online (Sandbox Code Playgroud)
在我的QPushButton上,我这样做:
if(pushStartStop->text().toLower() == "start")
{
pushStartStop->setText("Stop");
thread->start();
}
else
{
pushStartStop->setText("Start");
thread->quit();
}
Run Code Online (Sandbox Code Playgroud)
thread-> start()工作正常,StartWork()被调用,一切都很漂亮(GUI运行没有块等).
但是thread-> quit()没有做任何事情,它被调用(因为按钮改变文本),但就是这样.如果我只是调用worker-> StopWork()它可以工作,但我不能再启动它.
我尝试过thread-> exit(); 但结果是一样的.我也知道子类分类工作,但它看起来更丑陋,根据最近的Qt文档,子分类不再是最佳的.
提前致谢.
你有一个永远的循环:
void StartWork()
{
running = true;
while(running)
{
do work;
}
}
Run Code Online (Sandbox Code Playgroud)
此函数将循环,因此线程的事件循环在发出后立即被阻止started().因此,finished()不能发射.
解决方案1:
添加功能
void DoWork()
{
if(running)
{
do work
}
}
Run Code Online (Sandbox Code Playgroud)
对工人而言,改变
void StartWork()
{
running = true;
}
Run Code Online (Sandbox Code Playgroud)
然后,只需连接DoWork到线程中的计时器.
解决方案2:
改变功能
void StartWork()
{
running = true;
while(running)
{
do work;
QCoreApplication::processEvents();
}
}
Run Code Online (Sandbox Code Playgroud)
使用此解决方案,您将不得不在工作程序停止其作业时重新启动线程(StopWork()将强制此函数完成,因此事件循环将没有要处理的事件并且线程将完成).