QThread
使用QThread类来创建线程,是Qt中最简单的一种多线程实现方式,不过一般不建议使用,因为它的功能比较有限。
使用QThread的方式为:继承QThread并重写run()函数。
** ExportThread.h **
#ifndef EXPORTTHREAD_H #define EXPORTTHREAD_H #include <QThread> #include <QDebug> #include "Utilities.h" class ExportThread : public QThread { Q_OBJECT public: explicit ExportThread(QObject *parent = nullptr); // 设置导出参数 void setExportParams(int start = 1, int end = 10000, const QString& prefix = "numbers"); protected: void run() override; signals: void exportStarted(); void exportFinished(bool success, const QString& message); void progressUpdate(int current, int total); private: int m_start; int m_end; QString m_prefix; }; #endif // EXPORTTHREAD_H** ExportThread.cpp **
#include "ExportThread.h" #include <QDateTime> #include <QDir> ExportThread::ExportThread(QObject *parent) : QThread(parent) , m_start(1) , m_end(10000) , m_prefix("numbers") { } void ExportThread::setExportParams(int start, int end, const QString& prefix) { m_start = start; m_end = end; m_prefix = prefix; } void ExportThread::run() { qDebug() << "导出线程开始运行..."; emit exportStarted(); try { bool success = Utilities::writeNumbersToFile(m_start, m_end, m_prefix); if (success) { emit exportFinished(true, QString("文件导出成功!范围:%1-%2").arg(m_start).arg(m_end)); } else { emit exportFinished(false, "文件导出失败!"); } qDebug() << "导出线程完成"; } catch (const std::exception& e) { qDebug() << "导出过程中发生异常:" << e.what(); emit exportFinished(false, QString("导出过程中发生异常: %1").arg(e.what())); } }使用方式:
ExportThread *exportThread = new ExportThread(this); exportThread->setExportParams(1, 10000, "numbers"); exportThread->start();QObject的moveToThread方法实现多线程
QObject的moveToThread方法可以将一个QObject对象移动到指定的线程中,实现多线程。
使用方式:
QObject *obj = new QObject(); QThread *thread = new QThread(); obj->moveToThread(thread); thread->start();示例:
** FileExportWorker.h **
#ifndef FILEEXPORTWORKER_H #define FILEEXPORTWORKER_H #include <QObject> #include "Utilities.h" class FileExportWorker : public QObject { Q_OBJECT public: explicit FileExportWorker(QObject *parent = nullptr); void exportNumbers(int start, int end, const QString& prefix); signals: void progressUpdated(int current, int total); void statusUpdated(const QString& status); public slots: }; #endif // FILEEXPORTWORKER_H** FileExportWorker.cpp **
#include "FileExportWorker.h" #include <QFile> #include <QTextStream> #include <QDateTime> #include <QDir> #include <QDebug> #include <QThread> #include <QCoreApplication> FileExportWorker::FileExportWorker(QObject *parent) : QObject(parent) , m_start(1) , m_end(10000) , m_prefix("numbers") , m_shouldStop(false) { } void FileExportWorker::setExportParams(int start, int end, const QString& prefix) { m_start = start; m_end = end; m_prefix = prefix; } void FileExportWorker::doExport() { qDebug() << "Worker线程ID:" << QThread::currentThreadId(); qDebug() << "开始导出任务..."; m_shouldStop = false; emit exportStarted(); emit statusUpdated("正在准备导出..."); try { bool success = false; emit statusUpdated("使用自定义参数导出..."); success = exportNumbersWithProgress(); if (m_shouldStop) { emit exportFinished(false, "导出已被用户取消"); } else if (success) { emit exportFinished(true, QString("文件导出成功!范围:%1-%2").arg(m_start).arg(m_end)); } else { emit exportFinished(false, "文件导出失败!"); } } catch (const std::exception& e) { qDebug() << "导出过程中发生异常:" << e.what(); emit exportFinished(false, QString("导出过程中发生异常: %1").arg(e.what())); } qDebug() << "导出任务完成"; } void FileExportWorker::stopExport() { m_shouldStop = true; emit statusUpdated("正在停止导出..."); } bool FileExportWorker::exportNumbersWithProgress() { // 获取当前时间并格式化为文件名 QDateTime currentTime = QDateTime::currentDateTime(); QString timeString = currentTime.toString("yyyy-MM-dd_hh-mm-ss"); QString fileName = QString("%1_%2_to_%3_%4.txt") .arg(m_prefix) .arg(m_start) .arg(m_end) .arg(timeString); // 创建文件对象 QFile file(fileName); // 以写入模式打开文件 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { qDebug() << "无法创建文件:" << fileName; return false; } // 创建文本流 QTextStream out(&file); int total = m_end - m_start + 1; int count = 0; // 写入指定范围的数字 for (int i = m_start; i <= m_end; ++i) { if (m_shouldStop) { file.close(); QFile::remove(fileName); // 删除未完成的文件 return false; } out << i; count++; // 每10个数字换行 if (count % 10 == 0 || i == m_end) { out << "\n"; } else { out << " "; // 数字之间用空格分隔 } // 每处理100个数字发送一次进度更新 if (count % 100 == 0 || i == m_end) { emit progressUpdated(count, total); emit statusUpdated(QString("已处理 %1/%2 个数字").arg(count).arg(total)); // 让出CPU时间,允许其他操作 QCoreApplication::processEvents(); } } // 关闭文件 file.close(); qDebug() << "成功写入文件:" << fileName; qDebug() << "文件路径:" << QDir::currentPath() + "/" + fileName; qDebug() << "写入数字范围:" << m_start << "到" << m_end << ",共" << total << "个数字"; return true; }