UioShi
UioShi

Reputation: 21

My Thread Still Freezes My GUI

Okay, so I have a class file that scans through files (I plan to include other things to reduce the strain it has, but right now I am just trying to get the Thread working) that goes through the file system looking for a specific file. When it changes what folder it is looking at, it fires an event. This event is connected to a handler that attempts to add the current folder to a list. I am using a thread because in the main thread, it was stopping the GUI from responding. I want the scanning to have a cancel option, and that cannot happen with a frozen GUI.

So, my issue: The thread is still causing the GUI to freeze and I cannot do anything.

Here is my Scanner.h file

#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

Here is my Scanner.cpp file

#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();
}

Here is where I use the Scanner class

Scanner scan;
    connect(&scan, SIGNAL(fileFocusChange(QString)), this, SLOT(handleFileChange(QString)));
    scan.start();
    scan.wait();

and lastly, here is the SLOT handleFileChange

void LoadDialog::handleFileChange(QString fileName){
    this->ui->fileActionList->addItem(fileName);
}

So why is my GUI still freezing?

Upvotes: 0

Views: 252

Answers (1)

Daniel
Daniel

Reputation: 583

in Qt Assistant:

bool QThread::​wait(unsigned long time = ULONG_MAX)

Blocks the thread until either of these conditions is met:

1.The thread associated with this QThread object has finished execution (i.e. when it returns from run()). This function will return true if the thread has finished. It also returns true if the thread has not been started yet.

2.time milliseconds has elapsed. If time is ULONG_MAX (the default), then the wait will never timeout (the thread must return from run()). This function will return false if the wait timed out.

When this code run,

Scanner scan;
connect(&scan, SIGNAL(fileFocusChange(QString)), this, SLOT(handleFileChange(QString)));
scan.start();
scan.wait();

the GUI Thread is waiting for the scan.wait() return. But in Scanner::run():

void Scanner::run(){
    this->findFile("");
    exec();//Enters the event loop and waits until exit() is called
}

It never return.

Sorry for my poor English. Hope this could help you.

Upvotes: 1

Related Questions