《QT5.9 c++ 开发指南》第13章 QThread功能简介

Jamina ·
更新时间:2024-11-14
· 554 次阅读

先看一下QThread 类功能简单介绍

         将应用程序的线程称为主线程,额外创建的线程称为工作线程 。 一般在主线程里创建工作线程,井调用 start()开始执行工作线程的任务 。 start()会在 内 部调用 run()函数,进入工作线程的事件循环,在 run()函数里调用 exit()或 quit()可以结束线程的事件循环,或在主线程里调用 terminate() 强制结束线程。
         公共函数部分:


 那我们开始写一个小工程吧。

 

   

先看下运行的图吧:

页面布局如下:

这获取图片资源:

链接:图片资源      提取码:74g3 

提取后记得要加载在项目中。

好的,我们先需要写一个类 QDiceThread 继承与 QThread 如下面:

#ifndef QDICETHREAD_H #define QDICETHREAD_H #include class QDiceThread :public QThread { Q_OBJECT private: int m_seq=0;//掷骰子次数序号 int m_diceValue;//骰子点数 bool m_Paused = true; //掷一次骰子 bool m_stop=false; //停止线程 protected: void run() Q_DECL_OVERRIDE; //线程任务,重载run函数 public: QDiceThread(); void diceBegin(); //掷一次骰子 void dicePause(); //暂停 void stopThread(); //结束线程 signals: void newValue(int seg,int diceValue); //产生新点数的信号 由主线程的槽函数响应 }; #endif // QDICETHREAD_H

对应的cpp:

#include "qdicethread.h" #include QDiceThread::QDiceThread() { } void QDiceThread::run() { //线程任务 m_stop = false; //启动线程 m_stop=false m_seq = 0; //掷骰子次数 qsrand(uint(QTime::currentTime().msec())); //随机数初始化,qsrand是线程安全的 while (!m_stop) { if(!m_Paused) { m_diceValue = qrand(); //获取随机数 m_diceValue = (m_diceValue % 6) +1; m_seq++; emit newValue(m_seq,m_diceValue); //发送信号 } msleep(500); //线程休眠500ms } // 在 m_stop==true时结束线程任务 quit(); //相当于 exit(0),退出线程的事件循环 } void QDiceThread::diceBegin() { //开始掷骰子 m_Paused = false; } void QDiceThread::dicePause() { //暂停掷骰子 m_Paused = true; } void QDiceThread::stopThread() { //停止线程 m_stop = true; }  

如果你编译过程中出现下面错误,可能是你在创建这个类的时候,没有选择继承 Q_OBJECT:

 

解决方案:

解决方案与错误分析

如果没有我们继续:

这个是dialog.h 文件:

#ifndef DIALOG_H #define DIALOG_H #include #include "qdicethread.h" namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT private: QDiceThread threadA; protected: void closeEvent(QCloseEvent *event); public: explicit Dialog(QWidget *parent = nullptr); ~Dialog(); private slots: //自定义槽函数 void onthreadA_started(); void onthreadA_finished(); void onthreadA_newValue(int seq, int diceValue); void on_btnStartThread_clicked(); void on_btnDiceBegin_clicked(); void on_btnDiceEnd_clicked(); void on_btnStopThread_clicked(); void on_btnClear_clicked(); private: Ui::Dialog *ui; }; #endif // DIALOG_H

这个是dialog.cpp 文件:

#include "dialog.h" #include "ui_dialog.h" void Dialog::closeEvent(QCloseEvent *event) { //关闭窗口 并退出程序 if(threadA.isRunning()) { threadA.stopThread(); threadA.wait(); } event->accept(); } Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); //构造函数 connect(&threadA,SIGNAL(started()),this,SLOT(onthreadA_started())); connect(&threadA,SIGNAL(finished()),this,SLOT(onthreadA_finished())); connect(&threadA,SIGNAL(newValue(int,int)),this,SLOT(onthreadA_newValue(int,int))); } Dialog::~Dialog() { delete ui; } void Dialog::onthreadA_started() { //线程started()信号的响应槽函数 ui->LabA->setText("Thread 状态: thread started"); } void Dialog::onthreadA_finished() { //线程的 finished()信号的响应槽函数 ui->LabA->setText("Thread状态:thread finished"); } void Dialog::onthreadA_newValue(int seq, int diceValue) { //QDiceThread的newValue()信号的响应槽函数,显示骰子次数和点数 QString str = QString::asprintf("第 %d 次掷骰子,点数为:%d",seq,diceValue); ui->plainTextEdit->appendPlainText(str); QPixmap pic;//图片显示 QString filename = QString::asprintf(":/dice/images/d%d.jpg",diceValue); pic.load(filename); ui->LabPic->setPixmap(pic); } void Dialog::on_btnStartThread_clicked() { //开始线程 threadA.start(); //开始线程,会执行重载的run 函数 ui->btnStartThread->setEnabled(false); ui->btnStopThread->setEnabled(true); ui->btnDiceBegin->setEnabled(true); ui->btnDiceEnd->setEnabled(false); } void Dialog::on_btnDiceBegin_clicked() { //开始 掷骰子按钮 threadA.diceBegin(); ui->btnDiceBegin->setEnabled(false); ui->btnDiceEnd->setEnabled(true); } void Dialog::on_btnDiceEnd_clicked() { //暂停 掷骰子按钮 threadA.dicePause(); ui->btnDiceBegin->setEnabled(true); ui->btnDiceEnd->setEnabled(false); } void Dialog::on_btnStopThread_clicked() { //结束线程 threadA.stopThread(); threadA.wait(); ui->btnStartThread->setEnabled(true); ui->btnStopThread->setEnabled(false); ui->btnDiceBegin->setEnabled(false); ui->btnDiceEnd->setEnabled(false); } void Dialog::on_btnClear_clicked() { //清空文本 按钮 ui->plainTextEdit->clear(); }

大部分功能都有中文解释了,请慢慢理解,可以看这本书,对比来。

希望大家多多学习进步。


作者:比卡丘不皮



c+ qt5 C++ qthread

需要 登录 后方可回复, 如果你还没有账号请 注册新账号