使用Qt中的工作線程,模擬上傳文件(需要用到定時器,線程知識)

頭文件:

GBK.h

#ifndef _QT_GBK_H
#define _QT_GBK_H


#include <QString>
#include <QTextCodec>
#include <string>
using std::string;

class GBK
{
public:
	// QString(Unicode) -> std::string (GBK)
	static string FromUnicode(const QString& qstr)
	{
		QTextCodec* pCodec = QTextCodec::codecForName("gb2312");
		if(!pCodec) return "";	

		QByteArray arr = pCodec->fromUnicode(qstr);
		string cstr = arr.data();
		return cstr;
	}

	// std::string (GBK) -> QString(Unicode)
	static QString ToUnicode(const string& cstr)
	{
		QTextCodec* pCodec = QTextCodec::codecForName("gb2312");
		if(!pCodec) return "";

		QString qstr = pCodec->toUnicode(cstr.c_str(), cstr.length());
		return qstr;
	}

};


#endif

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFileDialog>
#include <QFile>
#include <QString>

#include "senddialog.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;
private slots:
    int OnOpenBtnChicked();
    int OnSendBtnChicked();
};

#endif // MAINWINDOW_H
senddialog.h
#ifndef SENDDIALOG_H
#define SENDDIALOG_H

#include <QDialog>

#include "sendtask.h"
#include <QTimer>
#include <QTime>

namespace Ui {
class SendDialog;
}

class SendDialog : public QDialog
{
    Q_OBJECT

public:
    explicit SendDialog(const QString &filepath, QWidget *parent = 0);
    ~SendDialog();
    void timerEvent(QTimerEvent *event);//定時器函數
private:
    Ui::SendDialog *ui;
    SendTask *m_task;
    int m_timerId;//定時器ID
};

#endif // SENDDIALOG_H
sendtask.h(創建時基類選擇繼承於QThread)
#ifndef SENDTASK_H
#define SENDTASK_H

#include <QThread>
#include <string>
#include <string.h>

class SendTask : public QThread
{
    Q_OBJECT
public:
    explicit SendTask(QObject *parent = 0);
    int BeginTask(const char *filepath);//開始線程
    void BendTask();//結束線程
    int GetStatus();//獲取狀態
    int GetProgress();//獲取進度
signals:

public slots:

private:
    void run();
    char m_filename[128];//打開文件名
    int m_filesize;//文件字節數
    int m_byteresed;//處理的總字節數
    int m_status;//任務的狀態
};

#endif // SENDTASK_H
源文件:

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->OpenButton,SIGNAL(clicked()),
            this,SLOT(OnOpenBtnChicked()));
    connect(ui->SendButton,SIGNAL(clicked()),
            this,SLOT(OnSendBtnChicked()));
}

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

int MainWindow::OnOpenBtnChicked()
{
    QString filepath = QFileDialog::getOpenFileName(this,"選擇文件");
    if(filepath.length() > 0)
    {
        ui->lineEdit->setText(filepath);
    }
    return 0;
}

int MainWindow::OnSendBtnChicked()
{
    QString filepath = ui->lineEdit->text();
    SendDialog dlg(filepath,this);
    dlg.exec();
    return 0;
}
senddialog.cpp
#include "senddialog.h"
#include "ui_senddialog.h"
#include <QTextCodec>
#include "GBK.h"

SendDialog::SendDialog(const QString &filepath,QWidget *parent) :
    QDialog(parent),
    ui(new Ui::SendDialog)
{
    ui->setupUi(this);
    string gbk_filepath = GBK::FromUnicode(filepath);
    m_task = new SendTask;
    m_task->BeginTask(gbk_filepath.c_str());

    m_timerId = startTimer(200);
}

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

void SendDialog::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == m_timerId)
    {
        int status = m_task->GetStatus();
        int progess = m_task->GetProgress();
        ui->progressBar->setValue(progess);

        if(status == 1)
        {
            //結束線程
            m_task->BendTask();
            delete m_task;
            //殺死定時器
            killTimer(m_timerId);
            this->accept();
        }
    }
}
sendtask.cpp
#include "sendtask.h"
#include <QDebug>

SendTask::SendTask(QObject *parent) :
    QThread(parent)
{
}

int SendTask::BeginTask(const char *filepath)
{
    strcpy(m_filename,filepath);
    m_filesize = 0;
    m_byteresed = 0;
    m_status = 0;
    start();

    return 0;
}

void SendTask::BendTask()
{
    wait();
}

int SendTask::GetStatus()
{
    return m_status;
}

int SendTask::GetProgress()
{
    if(m_filesize <= 0)
    {
        return 0;
    }
    return m_byteresed *100/m_filesize;
}

void SendTask::run()
{
    FILE *fpr = fopen(m_filename,"rb");
    if(!fpr)
    {
        m_status = -1;  //狀態發生錯誤
        return;
    }
    fseek(fpr,0,SEEK_END);
    m_filesize = ftell(fpr);
    rewind(fpr);
    char buf[1024*100];
    while(1)
    {
        int n = fread(buf,1,1024*100,fpr);
        if(n <= 0)
        {
            break;
        }
        m_byteresed += n;
        qDebug() << "Read: " << m_byteresed;
        QThread::msleep(200);
    }
    fclose(fpr);
    m_status = 1;
    qDebug() << "Complete...... ";
}
界面設計:

mainwindow.ui(用到了pushButton,Lable標籤,ToolButton,Line Edit)


senddialog.ui(用到了Progress Bar進度條)


注:選中Progress Bar 設置屬性value爲0可將進度條置零,如下圖;


效果圖:


:用的MP3文件測試,MP3文件既不會太大,亦不會很小比較合適模擬效果

發佈了75 篇原創文章 · 獲贊 32 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章