好的,所以我有一个扫描文件的类文件(我打算包含其他东西以减轻它所带来的压力,但现在我只是试图让Thread工作)通过文件系统寻找特定文件。当它改变它正在查看的文件夹时,它会触发一个事件。此事件连接到尝试将当前文件夹添加到列表的处理程序。我正在使用一个线程,因为在主线程中,它阻止了GUI的响应。我希望扫描具有取消选项,而冻结的GUI不会发生这种情况。
所以,我的问题:线程仍然导致GUI冻结,我无法做任何事情。
这是我的Scanner.h文件
#ifndef SCANNER_H
#define SCANNER_H
#include <QString>
#include <QObject>
#include <QThread>
class Scanner : public QThread
{
Q_OBJECT
public:
QString searchFile;
Scanner();
~Scanner();
void findFile(QString fileName);
void ScanFile(QString filePath);
signals:
void fileFocusChange(QString fileName);
void fileFound(QString fileName);
protected:
void run();
};
#endif // SCANNER_H
这是我的Scanner.cpp文件
#include "Scanner.h"
#include <QFileInfoList>
#include <QFileInfo>
#include <QDir>
#include <QDebug>
Scanner::Scanner()
{
}
Scanner::~Scanner()
{
}
void Scanner::ScanFile(QString filePath){
QDir dir = filePath;
QFileInfoList files = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
for(int i = 0; i < files.size(); i++){
//This limitation is here to slow down how many files it goes over in a second (It was making my Qt unresponsive)
QObject::thread()->usleep(500);
QFileInfo info = files[i];
if(info.isDir()){
emit fileFocusChange(info.absoluteFilePath());
this->ScanFile(info.absoluteFilePath());
}else{
qDebug() << info.absoluteFilePath();
if(info.fileName() == this->searchFile){
emit fileFound(info.absoluteFilePath());
}
}
}
}
void Scanner::findFile(QString fileName){
this->searchFile = fileName;
QFileInfoList drives = QDir::drives();
foreach(QFileInfo drive, drives){
this->ScanFile(drive.absoluteFilePath());
}
}
void Scanner::run(){
this->findFile("");
exec();
}
这是我使用Scanner类的地方
Scanner scan;
connect(&scan, SIGNAL(fileFocusChange(QString)), this, SLOT(handleFileChange(QString)));
scan.start();
scan.wait();
最后,这是SLOT handleFileChange
void LoadDialog::handleFileChange(QString fileName){
this->ui->fileActionList->addItem(fileName);
}
那么为什么我的GUI仍然冻结?
答案 0 :(得分:1)
:
bool QThread :: wait(unsigned long time = ULONG_MAX)
阻止线程,直到满足以下任一条件:
1.与此QThread对象关联的线程已完成执行(即从run()返回时)。如果线程已完成,此函数将返回true。如果线程尚未启动,它也会返回true。
2.time毫秒已过。如果时间是ULONG_MAX(默认值),那么等待将永远不会超时(线程必须从run()返回)。如果等待超时,此函数将返回false。
此代码运行时,
Scanner scan;
connect(&scan, SIGNAL(fileFocusChange(QString)), this, SLOT(handleFileChange(QString)));
scan.start();
scan.wait();
GUI Thread正在等待scan.wait()返回。但是在Scanner :: run()中:
void Scanner::run(){
this->findFile("");
exec();//Enters the event loop and waits until exit() is called
}
永远不会回来。
抱歉我的英语不好。希望这可以帮助你。