QT-多线程知识(例子:多线程下载小说)
来源:互联网 发布:卷积网络 pooling 编辑:程序博客网 时间:2024/05/29 05:55
一、新建一个线程类
继承QThread的一个线程类,实现run方法,同时要包含头文件
#include <QThread>
获取当前的线程id
currentThreadId()
线程睡眠(1秒)
sleep(1) 或msleep(1000) 或msleep(1000000)
线程优先级
setPriority()
线程让道
yieldCurrentThread()
线程终止
terminate()
线程开启
start()
线程等待
wait()
二、线程互斥
QMutex mt,通过lock与unlock来控制
QMutexLocker locker(&mt)
// 生产者消费者模式,即信号模式
QSemaphore freeBytes(80);
QSemaphore usedBytes(0);// 利用等待和唤醒来控制
三、多线程下载小说
1、mainwindow文件
#ifndef MAINWINDOW_H#define MAINWINDOW_H#pragma execution_character_set("utf-8")#include <QMainWindow>#include <QFileDialog>#include <QMessageBox>#include <QtNetwork>#include <QRegExp>#include "leaderthread.h"namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); ~MainWindow();private slots: void on_viewFile_clicked(); void on_startDown_clicked(); void onFinished(QNetworkReply* reply);public slots: void logWrite(QString log); void finishDown();private: Ui::MainWindow *ui; QString mvpath; QString module; QString bqgUrl; QString bookname; QList<QString> pageList; QNetworkAccessManager *netManager; QString getSubStr(QString str,QString start_str,QString end_str,qint32 start_len,qint32 end_len);};#endif // MAINWINDOW_H
#include "mainwindow.h"#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this); bqgUrl = "http://www.biquge.com/"; netManager = new QNetworkAccessManager(this); connect(netManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(onFinished(QNetworkReply*))); logWrite("www.biquge.com/xxx/(xxx即是小说代码)");}MainWindow::~MainWindow(){ delete ui;}void MainWindow::on_viewFile_clicked(){ QString dir = QFileDialog::getExistingDirectory(this,"选择小说的存放路径:",".",QFileDialog::ShowDirsOnly); ui->mvpath->setText(dir);}void MainWindow::on_startDown_clicked(){ mvpath = ui->mvpath->text(); if(mvpath.isEmpty()){ QMessageBox::warning(this,"错误","下载路径不能为空!");return; } module = ui->module->text(); if(module.isEmpty()){ QMessageBox::warning(this,"错误","小说代号不得为空!");return; } netManager->get(QNetworkRequest(QUrl(bqgUrl+module))); ui->startDown->setEnabled(false);}void MainWindow::onFinished(QNetworkReply* reply){ pageList.clear(); QByteArray arr = reply->readAll(); QString content(arr); QRegExp rx("/"+module+"/[0-9]{7,9}.html"); qint32 startPos = 0; qint32 pos = content.indexOf(rx,startPos); while( pos >= 0){ pageList.append(rx.cap(0)); pos = content.indexOf(rx,pos + rx.matchedLength()); } reply->deleteLater(); LeaderThread * leader = new LeaderThread(); leader->setList(pageList); leader->setParam(this,bqgUrl+module+"/",mvpath); leader->setBookName(getSubStr(content,"<div id=\"maininfo\">","</h1>",51,0)); leader->start();}void MainWindow::logWrite(QString log){ ui->log->append(log);}QString MainWindow::getSubStr(QString str,QString start_str,QString end_str,qint32 start_len,qint32 end_len){ qint32 pos_start = str.indexOf(QRegExp(start_str),0); if(pos_start == -1){ return ""; } qint32 pos_end = str.indexOf(QRegExp(end_str),pos_start); if(pos_end == -1){ return ""; } return str.mid(pos_start+start_len,pos_end-end_len-pos_start-start_len);}void MainWindow::finishDown(){ ui->startDown->setEnabled(true);}
2、开辟一个管理下载的线程LeaderThread
#ifndef LEADERTHREAD_H#define LEADERTHREAD_H#include <QThread>#include "mainwindow.h"#include "downloadthread.h"#include <QtAlgorithms>#pragma execution_character_set("utf-8")class LeaderThread : public QThread{ Q_OBJECTpublic: LeaderThread(); void setList(QList<QString>& list); void setParam(QMainWindow* wnd,QString baseUrl,QString path); void setBookName(QString bookname);signals: void sendLog(QString log); void finishDown();protected: void run(); void openMuchTread(qint32 n,qint32 start_pos);private: QList<QString> m_list; QMainWindow* wnd; QString baseUrl; QString path; QString bookname;};#endif // LEADERTHREAD_H
#include "leaderthread.h"LeaderThread::LeaderThread(){}void LeaderThread::run(){ QDir dir(path+"/tmp"); if(!dir.exists()){ dir.mkdir(path+"/tmp"); } QString filename = path + "/" + bookname + ".txt"; if(QFile::exists(filename)){ QFile::remove(filename); } connect(this,SIGNAL(sendLog(QString)),wnd,SLOT(logWrite(QString))); connect(this,SIGNAL(finishDown()),wnd,SLOT(finishDown())); qint32 listSize = m_list.size(); for(qint32 i = 0;i < listSize ; i=i+25){ if((listSize-i)>0 && (listSize-i) < 25){ openMuchTread(listSize-i,i); }else{ openMuchTread(25,i); } } QFile file(filename); if(!file.open(QFile::WriteOnly|QFile::Truncate)){ sendLog("小说全集打包失败,文件打开失败");return; } for(QString item : m_list){ QFile tmpfile(path + "/tmp/" + item); if(!tmpfile.open(QFile::ReadOnly)){ sendLog("文件没有打开:"+item);return; } file.write(tmpfile.readAll()); file.write("\r\n\r\n\r\n"); tmpfile.close(); QFile::remove(path + "/tmp/" + item); sendLog("打包临时文件:"+item); } file.close(); dir.rmdir(path + "/tmp"); QString logInfo; logInfo = QString("打包完成,共下载了%1章").arg(m_list.size()); sendLog(logInfo); finishDown(); quit();}void LeaderThread::setList(QList<QString>& list){ for(QString item : list){ int pos = item.indexOf(QRegExp("/"),1); QString newStr = item.mid(pos+1,7); if(!m_list.contains(newStr)) m_list.append(newStr); } qSort(m_list.begin(),m_list.end());}void LeaderThread::setParam(QMainWindow* wnd,QString baseUrl,QString path){ this->wnd = wnd; this->baseUrl = baseUrl; this->path = path;}void LeaderThread::openMuchTread(qint32 n,qint32 start_pos){ QList<DownloadThread*> downlist; for(qint32 i = 0 ;i < n ;++i){ QString page = m_list.at(start_pos + i); DownloadThread* downThread = new DownloadThread(wnd,baseUrl,page,path); downlist.append(downThread); downThread->start(); } for(DownloadThread* tr : downlist){ tr->wait(10000); } downlist.clear();}void LeaderThread::setBookName(QString bookname){ this->bookname = bookname;}
3、单个下载的线程DownloadThread
#ifndef DOWNLOADTHREAD_H#define DOWNLOADTHREAD_H#include <QThread>#include <QtNetwork>#include "mainwindow.h"#pragma execution_character_set("utf-8")class DownloadThread : public QThread{ Q_OBJECTpublic: DownloadThread(); DownloadThread(QMainWindow* wnd,QString baseUrl,QString page,QString path);protected: void run(); QString getContent(QString html); QString getSubStr(QString str,QString start_str,QString end_str,qint32 start_len,qint32 end_len);signals: void sendLog(QString log);private: QMainWindow* wnd; QString baseUrl; QString page; QString path;};#endif // DOWNLOADTHREAD_H
#include "downloadthread.h"DownloadThread::DownloadThread(){}DownloadThread::DownloadThread(QMainWindow* wnd,QString baseUrl,QString page,QString path){ this->wnd = wnd; this->baseUrl = baseUrl; this->page = page; this->path = path;}void DownloadThread::run(){ connect(this,SIGNAL(sendLog(QString)),wnd,SLOT(logWrite(QString))); QNetworkAccessManager * manager = new QNetworkAccessManager(this); QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(baseUrl + page + ".html"))); QEventLoop eventLoop; connect(reply,SIGNAL(finished()),&eventLoop,SLOT(quit())); eventLoop.exec(); QByteArray arr = reply->readAll(); QFile file(path + "/tmp/" + page); if(!file.open(QFile::WriteOnly)) { sendLog("存储页面"+page+"失败"); return; } QString html(arr); QString content = getContent(html); file.write(content.toUtf8()); file.close(); delete reply; delete manager; quit();}QString DownloadThread::getSubStr(QString str,QString start_str,QString end_str,qint32 start_len,qint32 end_len){ qint32 pos_start = str.indexOf(QRegExp(start_str),0); if(pos_start == -1){ return ""; } qint32 pos_end = str.indexOf(QRegExp(end_str),pos_start); if(pos_end == -1){ return ""; } return str.mid(pos_start+start_len,pos_end-end_len-pos_start-start_len);}QString DownloadThread::getContent(QString html){ QString title = getSubStr(html,"<div class=\"bookname\">","</h1>",34,0); QString content = getSubStr(html,"<div id=\"content\">","<div class=\"bottem2\">",43,70); content.replace(QRegExp(" ")," "); content.replace(QRegExp("<br/>"),"\r\n"); sendLog("下载完成:" + title); return title + "\r\n\r\n" + content;}
0 0
- QT-多线程知识(例子:多线程下载小说)
- 多线程小说下载
- Python多线程下载有声小说
- Qt多线程简单例子
- Qt 多线程例子
- QT多线程简单例子
- QT:多线程下载文件
- Qt多线程下载
- Qt 多线程的一个例子
- qt多线程的简单例子
- Qt---多线程应用的例子
- 多线程下载的代码例子
- 多线程知识(有例子) 转载 还行继续努力
- qt多线程一个简单的例子
- qt多线程一个简单的例子
- QT中多线程QWaitCondition例子解析
- 多线程知识(1)
- java多线程(例子)
- 【排序】直接选择排序
- poj入门水题整理5
- Yii2 - 02控制器、路由、Url生成
- Ubuntu16.04 安装Nginx
- Java学习
- QT-多线程知识(例子:多线程下载小说)
- 在CI中使用伪静态
- Java学习
- NOJ 1214 Catalan数
- MySQL执行计划解读
- 对象的行为
- yii2学习笔记——yii2引入微信API
- 怎样阅读一本书——概述
- lamp环境源码安装文档(centos7我已经试验过,没问题)