c++ - (QT) QThread 没有第二次执行
问题描述
我是线程新手并在做一个练习题,我正在编写一个程序,该程序在目录中创建文件列表并将其显示在QTableWidget
. 它使用一个单独的线程来进行文件查找。QThread
由于这个问题,我没有分类。当我运行程序并搜索目录时,它第一次运行良好,并按预期在表格视图中显示文件的名称。但是当我再次尝试时,它QTableView
不会更新。
在调试时,我注意到我在fileFinder
课堂上的断点在第二次尝试时没有被触发。似乎该线程第二次没有像第一次那样再次运行,我不知道为什么。我很确定这是我遗漏的一个简单错误。任何帮助将不胜感激。编码:
主窗口.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
主窗口.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;
}
文件查找器.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
文件查找器.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
}
}
解决方案
此行将在完成后销毁您的线程对象
connect(&workerThread, SIGNAL(finished()), finder, SLOT(deleteLater()));
您需要将线程保留为指针并在开始之前重新创建它。
在主窗口.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()));
推荐阅读
- botframework - 我们如何使用属性在 bot framework composer 中显示值的总和?
- html - Blazor:设置动态生成的 CSS 属性组件的标签
- python - 具有按日期时间范围排序的列的 Pandas Dataframe 数据透视表
- python - 使用 Flask Marshmallow Schema 解析枚举输出
- security - 何时应该实现刷新令牌以及如何保持无状态?
- c# - 如何在元组数组中找到具有最小项的元组
- flutter - Flutter:为什么 setState(( ) { }) 一次又一次地设置数据
- django - Django:保存外键
- python - 如何在一个 Django 模板中显示所有类别
- ruby-on-rails - Rails 6 Active Text + Trix + Active Storage:从 S3 中删除文件