我的线程仍然冻结我的GUI

时间:2015-02-28 02:40:41

标签: c++ multithreading qt

好的,所以我有一个扫描文件的类文件(我打算包含其他东西以减轻它所带来的压力,但现在我只是试图让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仍然冻结?

1 个答案:

答案 0 :(得分:1)

在Qt助理中

  

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
}

永远不会回来。

抱歉我的英语不好。希望这可以帮助你。