QThread创建多线程程序

18 篇文章 0 订阅

我们都知道一个程序一般只有一个线程,但是单独的线程面对一些小号耗时的操作效果会不好,引入单独的线程解决耗时的操作,并且与主线程之间处理好同步与数据交互,用处十分大。
今天通过一个简单的掷色子程序描述这一过程:
程序运行如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这个就是创建一个带有ui设计器的项目,然后在项目中创建一个C++类QDiceThread
然后大家跟我复制代码:
qdicethread.h:

#ifndef QDICETHREAD_H
#define QDICETHREAD_H
#include <QThread>

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;
public:
    QDiceThread();
    void diceBegin();
    void dicePause();
    void stopThread();
signals:
    void newValue(int seq,int diceValue);
};

#endif // QDICETHREAD_H

qdicethread.cpp:

#include "qdicethread.h"
#include <QTime>
QDiceThread::QDiceThread()
{

}
//开始掷色子
void QDiceThread::diceBegin()
{
    m_Paused=false;

}
//暂停掷色子
void QDiceThread::dicePause()
{
    m_Paused=true;
}
//停止线程
void QDiceThread::stopThread()
{
    m_stop=true;
}
//线程任务
void QDiceThread::run()
{
    m_stop=false;
    m_seq=0;
    //随机数初始化 qsrand是线程安全的
    qsrand(QTime::currentTime().msec());
    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);
    }
    quit();
}

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "qdicethread.h"
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    QDiceThread threadA;
protected:
    void closeEvent(QCloseEvent *event);
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void on_btn_qd_clicked();

    void on_btn_start_clicked();

    void on_btn_down_clicked();

    void on_btn_over_clicked();

    void on_btn_clear_clicked();

    //自定义槽函数
    void onthreadA_started();
    void onthreadA_finished();
    void onthread_newValue(int seq,int diceValue);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp:


#include "mainwindow.h"
#include "ui_mainwindow.h"
#pragma execution_character_set("utf-8")
#include <QDebug>



MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    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(onthread_newValue(int,int)));
}

void MainWindow::onthreadA_started()
{
    ui->label_state->setText("线程状态:thread started");
}

void MainWindow::onthreadA_finished()
{
     ui->label_state->setText("线程状态:thread over");
}

void MainWindow::onthread_newValue(int seq, int diceValue)
{
    QString str=QString::asprintf("第 %d 次掷色子,点数为: %d",seq,diceValue);
    ui->plainTextEdit->appendPlainText(str);
}

//启动线程
void MainWindow::on_btn_qd_clicked()
{
    threadA.start();
    //启动线程
    ui->btn_qd->setEnabled(false);
    //结束线程
    ui->btn_over->setEnabled(true);
    //开始按钮
    ui->btn_start->setEnabled(true);
    //暂停按钮
    ui->btn_down->setEnabled(false);
}
//结束线程
void MainWindow::on_btn_over_clicked()
{
    threadA.stopThread();
    threadA.wait();
    ui->btn_qd->setEnabled(true);
    ui->btn_over->setEnabled(false);
    ui->btn_start->setEnabled(false);
    ui->btn_down->setEnabled(false);
}
//开始
void MainWindow::on_btn_start_clicked()
{
    threadA.diceBegin();
    ui->btn_start->setEnabled(false);
    ui->btn_down->setEnabled(true);


}
//暂停
void MainWindow::on_btn_down_clicked()
{
    threadA.dicePause();
    ui->btn_start->setEnabled(true);
    ui->btn_down->setEnabled(false);

}

//清空
void MainWindow::on_btn_clear_clicked()
{

    ui->plainTextEdit->clear();
}
void MainWindow::closeEvent(QCloseEvent *event)
{
    if(threadA.isRunning()){
        threadA.stopThread();
        threadA.wait();
    }
    event->accept();

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




mainwindow.ui:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>951</width>
    <height>817</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="QWidget" name="widget" native="true">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>50</y>
      <width>881</width>
      <height>571</height>
     </rect>
    </property>
    <widget class="QPlainTextEdit" name="plainTextEdit">
     <property name="geometry">
      <rect>
       <x>20</x>
       <y>90</y>
       <width>831</width>
       <height>471</height>
      </rect>
     </property>
    </widget>
    <widget class="QPushButton" name="btn_qd">
     <property name="geometry">
      <rect>
       <x>20</x>
       <y>10</y>
       <width>111</width>
       <height>41</height>
      </rect>
     </property>
     <property name="text">
      <string>启动按钮</string>
     </property>
    </widget>
    <widget class="QPushButton" name="btn_start">
     <property name="geometry">
      <rect>
       <x>150</x>
       <y>10</y>
       <width>111</width>
       <height>41</height>
      </rect>
     </property>
     <property name="text">
      <string>开始</string>
     </property>
    </widget>
    <widget class="QPushButton" name="btn_down">
     <property name="geometry">
      <rect>
       <x>290</x>
       <y>10</y>
       <width>111</width>
       <height>41</height>
      </rect>
     </property>
     <property name="text">
      <string>暂停</string>
     </property>
    </widget>
    <widget class="QPushButton" name="btn_over">
     <property name="geometry">
      <rect>
       <x>430</x>
       <y>10</y>
       <width>111</width>
       <height>41</height>
      </rect>
     </property>
     <property name="text">
      <string>结束线程</string>
     </property>
    </widget>
    <widget class="QPushButton" name="btn_clear">
     <property name="geometry">
      <rect>
       <x>570</x>
       <y>10</y>
       <width>111</width>
       <height>41</height>
      </rect>
     </property>
     <property name="text">
      <string>清空文本</string>
     </property>
    </widget>
   </widget>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>20</y>
      <width>161</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>线程</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_state">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>640</y>
      <width>611</width>
      <height>111</height>
     </rect>
    </property>
    <property name="font">
     <font>
      <pointsize>16</pointsize>
      <weight>75</weight>
      <bold>true</bold>
     </font>
    </property>
    <property name="text">
     <string>TextLabel</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>951</width>
     <height>17</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

运行后程序如上所示,这个程序的点还是很多复习了Qthread的知识,Qtime等等,有用的很多,C++的面向对象体现的淋漓尽致。
大家不懂留言,我会一一解答

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值