我是线程和练习问题的新手,我正在编写一个程序,该程序在目录中创建文件列表并将其显示在QTableWidget
中。它使用单独的线程进行文件查找。由于this问题,我没有从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
}
}
答案 0 :(得分:3)
此行将在完成后破坏线程对象
connect(&workerThread, SIGNAL(finished()), finder, SLOT(deleteLater()));
您需要保留线程作为指针,并在开始之前重新创建它。
在mainwindow.h
QThread* workerThread;
然后
workerThread = new QThread;
finder->moveToThread(workerThread);
connect(workerThread, SIGNAL(started()), finder, SLOT(run()));
connect(finder, SIGNAL(name(QString)), this, SLOT(addToTable(QString)));
connect(workerThread, SIGNAL(finished()), finder, SLOT(deleteLater()));
答案 1 :(得分:1)
进行2次更改:
btn_Browse_clicked()
和new QThread()
分配给workerThread 对不起,我不知道为什么会这样,但确实如此。 也许其他人知道答案,我都会对此感兴趣。