您的位置:首页 > 编程语言 > Qt开发

Qt多线程笔记 (1)

2016-05-03 16:02 549 查看
需求:针对每个 *.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()];
这样的写发。
作为笔记记录之,也希望大牛给予指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: