# Qt子线程读文件
**Repository Path**: ss103838/qt-sub-thread-reads-files
## Basic Information
- **Project Name**: Qt子线程读文件
- **Description**: Qt使用子线程读文件
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2025-04-04
- **Last Updated**: 2025-10-16
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Qt子线程
## README
Qt项目中,如遇到复杂的,耗时的任务,如果不经过子线程处理,会导致界面卡顿;
用子线程处理文件在项目中使用频率比较高,本案写一个简单的子线程处理文件的Demo;

之所以说使用频繁,因为项目中大多对文件操作的项目还比较多,只要稍加修改即可应对大多数项目;
第一步: 界面布局

界面简单不做过多解释;
```xml
Widget
0
0
278
149
Widget
-
-
-
选择文件
-
子线程遍历文件
```
第二步:
先介绍重点:
在widget里面先创建建一个线程并开启

```
以上有两个要点: 第一个: 线程要开启;否则对应的槽函数不会执行第二个:主界面一定要通过信号触发槽函数,否则还是主线程去执行文件遍历
```
widget.h
```c++
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
class ReadFile;
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_threadBtn_clicked();
void on_selectBtn_clicked();
signals:
void readFileEmit(QString path);
private:
Ui::Widget *ui;
QThread* thread;
ReadFile* readFile;
QProgressDialog progressDialog;
};
#endif // WIDGET_H
```
widget.cpp
```c++
#include "widget.h"
#include "ui_widget.h"
#include "readfile.h"
#include
#include
#include
#include
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
,thread(new QThread)
,readFile(new ReadFile)
{
ui->setupUi(this);
qDebug()<<"Widget threadId"<moveToThread(thread);
connect(this,&Widget::readFileEmit,readFile,&ReadFile::readFile);
progressDialog.setWindowTitle("任务进度");
progressDialog.setWindowModality(Qt::WindowModal); // 设置为模态对话框
// 调用reset函数,里面对定时器进行了stop,因此就不再会自动弹出
progressDialog.reset();
connect(readFile, &ReadFile::currentValue, &progressDialog, &QProgressDialog::setValue);
thread->start();
}
Widget::~Widget()
{
thread->quit();
thread->wait();
delete ui;
}
void Widget::on_threadBtn_clicked()
{
emit readFileEmit(ui->filePath->text());
// 千万不能使用下面的调用方式,这样只会让主线程执行文件的遍历
// readFile->readFile(ui->filePath->text());
}
void Widget::on_selectBtn_clicked()
{
QString path = QFileDialog::getOpenFileName(nullptr,"Open Text File",QDir::homePath(),"Text Files (*.txt);;All Files(*)");
if(path.isEmpty())
{
QMessageBox::warning(this,"选择文件","选择的文件不能为空");
return;
}
ui->filePath->setText(path);
}
```
ReadFile类中,读文件

ReadFile.h
```c++
#ifndef READFILE_H
#define READFILE_H
#include
class ReadFile : public QObject
{
Q_OBJECT
public:
explicit ReadFile(QObject *parent = nullptr);
public slots:
void readFile(QString path);
signals:
void currentValue(int);
};
#endif // READFILE_H
```
ReadFile.cpp
```c++
#include "readfile.h"
#include
#include
#include
ReadFile::ReadFile(QObject *parent)
: QObject{parent}
{
}
void ReadFile::readFile(QString path)
{
qDebug()<<"ReadFile threadId"<
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
```
**总结:**
代码比较简单,但是有几个关键点
```
第一个: 线程一定要开启,否则槽函数不会执行;
第二个: 主界面一定要通过信号触发执行的槽函数,否则还是主线程去执行
第三点: 进度条默认会显示,因为进度条中有定时器,需要reset才不会显示
```
```
thread.start();
connect(this,&Widget::readFileEmit,readFile,&ReadFile::readFile);
```