我正在尝试为Scanner类创建一个线程,该线程处理该特定类的所有事件,从而释放GUI线程。我的GUI上有一个退出按钮,它只需调用qApp->quit()即可退出应用程序,但我不知道如何处理Scanner类中的线程。当应用程序退出时,我在调试日志中看到以下错误。
QThread::wait: Thread tried to wait on itself
QThread::wait: Thread tried to wait on itself
QThread: Destroyed while thread is still running
在Scanner.cpp中(省略其他功能)
Scanner::Scanner() :
{
this->moveToThread(&m_thread);
connect(&m_thread, &QThread::finished, this, &QObject::deleteLater);
connect(this, SIGNAL(StartEnroll()), this, SLOT(StartEnrollment()));
m_thread.start();
}
Scanner::~Scanner()
{
m_thread.quit(); // Not sure if this is the correct
m_thread.wait();
}
在主窗口.cpp中(省略其他功能)
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->ExitButton, SIGNAL(released()), this, SLOT(Quit()));
connect(&m_scanner, SIGNAL(FinishedEnroll(bool)), this, SLOT(EnrollDone(bool)));
}
void MainWindow::Quit()
{
close();
qApp->quit();
}
关于如何安全退出的任何指针在多线程应用程序中退出应用程序。
您需要让Scanner
类知道应用程序正在退出。
在MainWindow
的构造函数中添加以下行
connect(qApp, SIGNAL(aboutToQuit()), &m_scanner, SLOT(deleteLater()));
更新:
connect(&m_thread, &QThread::finished, this, &QObject::deleteLater);
不应在Scanner
的构造函数中
和
m_thread.quit();
m_thread.wait();
不应在Scanner
的析构函数中
事实上,m_thread
无论如何都不应该是Scanner
的一部分。QThread
类不代表线程,它是一个线程管理器,应该由创建它的线程拥有和控制。
在Qt中有许多使用线程的方法,其中许多没有很好地记录。如果你想使用
workerObject->moveToThread(&thread);
thread.start();
使用线程的方式,那么m_thread
应该是MainWindow
类的成员,并且这些函数调用应该在它的构造函数中进行。
感谢您的澄清和上面发布的解决方案。以下是我根据之前发布的内容所做的操作。
扫描仪线程.h
#include <QThread>
class ScannerThread : public QThread
{
public:
ScannerThread();
~ScannerThread();
};
扫描仪线程.cpp
#include "scannerthread.h"
ScannerThread::ScannerThread()
{
connect(this, &QThread::finished, this, &QObject::deleteLater);
}
ScannerThread::~ScannerThread()
{
quit();
wait();
}
在主窗口.h 中
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void Quit();
private:
Ui::MainWindow *ui;
Scanner m_scanner;
ScannerThread m_scannerThread;
};
在MainWindow.cpp中(省略其他功能)
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_scanner.moveToThread(&m_scannerThread);
m_scannerThread.start();
connect(ui->ExitButton, SIGNAL(released()), this, SLOT(Quit()));
connect(qApp, SIGNAL(aboutToQuit()), &m_scanner, SLOT(deleteLater()));
}
void MainWindow::Quit()
{
close();
qApp->quit();
}
这对我来说似乎很好。如果你看到任何错误,请纠正,谢谢你的帮助。
首先,您应该将QThread
移出Scanner类。QThread
管理一个线程,因此您不能在该线程内部调用与线程管理相关的函数。这就是您收到关于线程正在等待自身的消息的原因。
你应该有这样的东西:
m_scanner.moveToThread(&m_thread);//make the thread a member of your window
m_thread.start();
然后,在您的quit
函数中,根据您的意愿,在退出之前等待线程(更好)或终止线程(更糟),或者进行权衡,例如:
void MainWindow::Quit()
{
close();
//Wait maximum 1 second
if(!m_thread.wait(1000) {
m_thread.terminate();
}
qApp->quit();
}