Я новичок в работе с потоками и задаю вопрос об упражнении, где я пишу программу, которая создает список файлов в каталоге и отображает его в QTableWidget
. Он использует отдельный поток для поиска файла. Я не подклассифицирую от QThread
из-за этого вопроса. Когда я запускаю программу и ищу каталог, он работает нормально с первого раза и отображает имена файлов в табличном представлении, как и ожидалось. Но когда я пытаюсь сделать это снова, QTableView
не обновляется.
Во время отладки я замечаю, что мои контрольные точки в моем классе fileFinder
не срабатывают со второй попытки. Кажется, что поток не запускается снова во второй раз, как это происходит в первый раз, и я не могу понять, почему. Я уверен, что это простая ошибка, которую я пропускаю. Любая помощь будет оценена. Код:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "filefinder.h"
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void addToTable(QString name);
void on_btnBrowse_clicked();
private:
Ui::MainWindow *ui;
QThread workerThread;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//set up tableWidget code here omitted
}
void MainWindow::on_btnBrowse_clicked()
{
//clear tableWidget contents
ui->tableFiles->setRowCount(0);
fileFinder *finder = new fileFinder;
finder->moveToThread(&workerThread);
connect(&workerThread, SIGNAL(started()), finder, SLOT(run())); //execute run() function when worker thread has started
connect(finder, SIGNAL(name(QString)), this, SLOT(addToTable(QString))); //pass names from thread to handler slot
connect(&workerThread, SIGNAL(finished()), finder, SLOT(deleteLater())); //delete thread when done
//get directory
QString dir = QFileDialog::getExistingDirectory(this, "Select Directory", "/home", QFileDialog::ShowDirsOnly);
ui->dirEdit->setText(dir);
//set directory in thread object
finder->setDir(dir);
//start worker thread
workerThread.start();
}
//add each name to tableWidget one at a time
void MainWindow::addToTable(QString name)
{
QTableWidgetItem *fileName = new QTableWidgetItem(name);
int row = ui->tableFiles->rowCount();
ui->tableFiles->insertRow(row);
ui->tableFiles->setItem(row, 0, fileName);
}
MainWindow::~MainWindow()
{
workerThread.quit();
workerThread.wait();
delete ui;
}
filefinder.h
#ifndef FILEFINDER_H
#define FILEFINDER_H
#include <QStringList>
#include <QThread>
class fileFinder : public QObject
{
Q_OBJECT
public:
fileFinder();
void searchDir();
void setDir(QString path);
public slots:
void run();
signals:
void name(QString n);
private:
QStringList files;
QString m_dir;
};
#endif // FILEFINDER_H
filefinder.cpp
#include "filefinder.h"
#include <unistd.h>
#include <QDir>
fileFinder::fileFinder()
{
}
//return list of all files in the directory
void fileFinder::searchDir()
{
QDir dir;
dir.setPath(m_dir);
//get list of file names sorted by name
files = dir.entryList(QDir::Files, QDir::Name);
}
//set the selected directory
void fileFinder::setDir(QString path)
{
m_dir = path;
}
//executed when thread is started
void fileFinder::run()
{
searchDir();
//iterate through list of files and emit names one by one
foreach(QString f, files){
emit(name(f));
usleep(100); //pause inbetween emits
}
}