使用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文件既不会太大,亦不会很小比较合适模拟效果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt Creator 多线程读取文件到程序显示 利用QT Creator多任务读取一个文档到程序里 为了防止直接读取文件里的内容太大而发生卡顿,于是多线程读取将更高效的解决这个问题。 效果图如下: 其pro文件无需改动,默认就好,头文件h里面的内容为 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MyObj; class MyObj : public QObject { Q_OBJECT public: MyObj(); //新的线程 signals: void toLine(QString line); private slots: void doWork(); }; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void appendText(QString); //定义一个槽 private: Ui::MainWindow *ui; QThread *t; MyObj *obj; }; #endif // MAINWINDOW_H 而MAIN主文件的内容为了防止文乱码做了如下修改: #include "mainwindow.h" #include #include int main(int argc, char *argv[]) { QApplication a(argc, argv); //设置文字体 防止乱码 a.setFont(QFont("Microsoft Yahei", 9)); //设置文编码 #if (QT_VERSION <= QT_VERSION_CHECK(5,0,0)) #if _MSC_VER QTextCodec *codec = QTextCodec::codecForName("GBK"); #else QTextCodec *codec = QTextCodec::codecForName("UTF-8"); #endif QTextCodec::setCodecForLocale(codec); QTextCodec::setCodecForCStrings(codec); QTextCodec::setCodecForTr(codec); #else QTextCodec *codec = QTextCodec::codecForName("UTF-8"); QTextCodec::setCodecForLocale(codec); #endif MainWindow w; w.show(); return a.exec(); } 接下来重点来了,源文件CPP里为 #include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); t = new QThread(); //QThread obj = new MyObj(); obj->moveToThread(t); qDebug()<<"main thread:"<<QThread::currentThread(); connect(t,SIGNAL(started()), obj, SLOT(doWork())); connect(obj,SIGNAL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值