Qt多线程笔记 (1)

需求:针对每个 *.dat文件开辟一个线程,用于处理相应的事务(将第一行数据用第二行来替换)。

先贴自己弄的方法,抛砖引玉:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFileDialog>
#include <QDebug>
#include <QStandardItemModel>
#include <QMessageBox>
#include <QGridLayout>
#include <QHeaderView>

#include "WorkThread.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QStringList gasFileList;

    qint32 iLastRowCnt;

signals:
    void SigSendFileName(qint32, QString);

private slots:
    void OpenFile();

    void SendFiles();

    void UpdateStatus(qint32 iRow, QString sStatus);
};

#endif // MAINWINDOW_H
mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    iLastRowCnt = 0;

    qDebug()<<"MainWindow thread Id:"<<this->thread()->currentThreadId();

    ui->mainToolBar->setFixedHeight(60);

    this->setCentralWidget(ui->tableWidget);

    ui->tableWidget->setColumnCount(2);

    QStringList header;
    header<<tr("文件名")<<tr("状态");
    ui->tableWidget->setHorizontalHeaderLabels(header);

    ui->tableWidget->setColumnWidth(0,500);
    ui->tableWidget->setColumnWidth(1,200);

    ui->actionReplace->setEnabled(false);

    gasFileList.clear();

    connect(ui->actionOpenFile, SIGNAL(triggered()), this, SLOT(OpenFile()));

    connect(ui->actionReplace, SIGNAL(triggered()), this, SLOT(SendFiles()));

    connect(ui->actionClose, SIGNAL(triggered()), this, SLOT(close()));

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::OpenFile()
{
    ui->actionReplace->setEnabled(false);

   qDebug()<<"last row count:"<<iLastRowCnt;

    ui->tableWidget->clearContents();

    gasFileList.clear();


    gasFileList = QFileDialog::getOpenFileNames(this,
                                                tr("打开待修改的文件"),
                                                "D:/",
                                                tr("待修改的文件 (*.dat)"));

    //qDebug()<<"Opened File list:"<<gasFileList;

    iLastRowCnt = gasFileList.count();

    if(!gasFileList.isEmpty())
    {
        ui->actionReplace->setEnabled(true);
    }

    for(qint32 i = 0; i < gasFileList.count(); i++)
    {
        ui->tableWidget->insertRow(i);

        ui->tableWidget->setItem(i,0,new QTableWidgetItem(gasFileList.at(i)));
        ui->tableWidget->setItem(i,1,new QTableWidgetItem(tr("Wait")));
    }

}

void MainWindow::SendFiles()
{
    //qDebug()<<"Emit file list to an new thread!";

    qDebug()<<"File count:"<<gasFileList.count();

    WorkThread *poWork;

    poWork = new WorkThread[gasFileList.count()];

    for(qint32 i = 0; i < gasFileList.count(); i++)
    {
        connect(this, SIGNAL(SigSendFileName(qint32, QString)), &poWork[i], SLOT(DoWork(qint32, QString)));

        connect(&poWork[i], SIGNAL(SigStatus(qint32, QString)), this, SLOT(UpdateStatus(qint32, QString)));

        emit SigSendFileName(i, gasFileList.at(i));

        disconnect(this, SIGNAL(SigSendFileName(qint32, QString)), &poWork[i], SLOT(DoWork(qint32, QString)));

    }
}

void MainWindow::UpdateStatus(qint32 iRow, QString sStatus)
{

    ui->tableWidget->setItem(iRow, 1, new QTableWidgetItem(sStatus));
}

workthread.h:
#ifndef WORKTHREAD_H
#define WORKTHREAD_H

#include <QObject>
#include <QThread>
#include <QDebug>
#include <QFile>

class WorkThread : public QObject
{
    Q_OBJECT
public:
    explicit WorkThread(QObject *parent = 0);

    QThread *poThread;
signals:
    void SigStatus(qint32, QString);

private slots:
    void DoWork(qint32 iRow, QString sFileName);


};

#endif // WORKTHREAD_H
workThread.cpp:
#include "workthread.h"

WorkThread::WorkThread(QObject *parent) :
    QObject(parent)
{
    poThread = new QThread;

    this->moveToThread(poThread);

    poThread->start();
}


void WorkThread::DoWork(qint32 iRow, QString sFileName)
{
    qDebug()<<"Work thread Id:"<<this->thread()->currentThreadId()<<"Work thread received file name:"<<sFileName;

    QStringList asAllRow;
    asAllRow.clear();

    QString sStatus;
    sStatus.clear();

    /* Open file */
    QFile oFileRead(sFileName);

    if(!oFileRead.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug()<< "Cannot open file for read:"<<qPrintable(oFileRead.errorString());
        return;
    }

    sStatus.append("1, Reading file~~~~~");
    emit SigStatus(iRow, sStatus);

    /* Read file */
    QTextStream oTextStreamIn(&oFileRead);
    oTextStreamIn.setCodec("UTF-8");

    /* Each line is stored as a string to the list of strings. */
    while (!oTextStreamIn.atEnd())
    {
        asAllRow.append(oTextStreamIn.readLine());
    }
    oFileRead.close();

    //qDebug()<<asAllRow.count();

    if(asAllRow.count() < 2)
    {
        qDebug()<<"Less than 2 row!";
        return;
    }

    sStatus.clear();
    sStatus.append("2, Replacing file~~~");
    emit SigStatus(iRow, sStatus);

    /* Replace */
    asAllRow.replace(1, asAllRow.at(2));

    /* Open file */
    QFile oFileWrite(sFileName);

    if(!oFileWrite.open(QIODevice::WriteOnly | QIODevice::Text | QFile::Truncate))
    {
        qDebug()<< "Cannot open file for write:"<<qPrintable(oFileWrite.errorString());
        return;
    }

    sStatus.clear();
    sStatus.append("3, Writing file~~~~~");
    emit SigStatus(iRow, sStatus);

    QTextStream oTextStreamOut(&oFileWrite);

    oTextStreamOut.setCodec("UTF-8");

    for(qint32 iOut = 0; iOut < asAllRow.count(); iOut++)
    {
        oTextStreamOut<<asAllRow.at(iOut)<<"\n";
    }

    oTextStreamOut.flush();

    oFileWrite.close();

    sStatus.clear();
    sStatus.append("4, Finished!~~~~~~~~");

    emit SigStatus(iRow, sStatus);

    //sFileName.clear();
}

中间出现过小插曲,connect 之后没有disconnect,导致原来的connect 依旧对后续的connect有效,这是不允许的。

作为新手,第一次看见

 poWork = new WorkThread[gasFileList.count()];
这样的写发。
 
作为笔记记录之,也希望大牛给予指正。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值