1.工程文件
#-------------------------------------------------
#
# Project created by QtCreator 2023-04-16T14:09:24
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = DiceThreadQMutex
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
main.cpp \
dialog.cpp \
qdicethread.cpp
HEADERS += \
dialog.h \
qdicethread.h
FORMS += \
dialog.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
res.qrc
2.线程类
#ifndef QDICETHREAD_H
#define QDICETHREAD_H
#include <QThread>
#include <QMutex>
class QDiceThread : public QThread
{
Q_OBJECT
private:
QMutex m_mutex;
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 diceEnd();
void stopThread();
bool readValue(int *seq, int *diceValue);
};
#endif // QDICETHREAD_H
#include "qdicethread.h"
#include <QTime>
QDiceThread::QDiceThread()
{
}
void QDiceThread::diceBegin()
{
m_paused=false;
}
void QDiceThread::diceEnd()
{
m_paused=true;
}
void QDiceThread::stopThread()
{
m_stop=true;
}
bool QDiceThread::readValue(int *seq, int *diceValue)
{
if(m_mutex.tryLock())
{
*seq = m_seq;
*diceValue = m_diceValue;
m_mutex.unlock();
return true;
} else {
return false;
}
}
void QDiceThread::run()
{
m_stop = false;
m_seq = 0;
// qsrand(QTime::currentTime().msec());
while(!m_stop)
{
if(!m_paused)
{
m_mutex.lock();
m_diceValue = qrand();
m_diceValue = (m_diceValue % 6 ) + 1;
m_seq++;
m_mutex.unlock();
}
msleep(500);
}
}
这里定义了QMutex 的成员变量m_mutex
与成员函数readValue;
3.显示对话框类
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QTimer>
#include "qdicethread.h"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
private:
int mSeq,mDiceValue;
QDiceThread threadA;
QTimer mTimer;//定时器
protected:
void closeEvent(QCloseEvent *event);
public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog();
private slots:
void on_btnStartThread_clicked();
void on_btnDiceBegin_clicked();
void on_btnDiceEnd_clicked();
void on_btnStopThread_clicked();
void on_btnClear_clicked();
void onthreadA_started();
void onthreadA_finished();
void onTimeOut(); //定期器处理槽函数
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
#pragma execution_character_set("utf-8")
#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(&mTimer,SIGNAL(timeout()),this,SLOT(onTimeOut()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::onthreadA_started()
{
ui->LabA->setText("Thread状态:thread started");
}
void Dialog::onthreadA_finished()
{
ui->LabA->setText("Thread状态:thread finished");
}
void Dialog::onTimeOut()
{ //定时器到时处理槽函数
int tmpSeq=0,tmpValue=0;
bool valid=threadA.readValue(&tmpSeq,&tmpValue); //读取数值
if (valid && (tmpSeq!=mSeq)) //有效,并且是新数据
{
mSeq=tmpSeq;
mDiceValue=tmpValue;
QString str=QString::asprintf("第 %d 次掷骰子,点数为:%d",mSeq,mDiceValue);
ui->plainTextEdit->appendPlainText(str);
QPixmap pic;
QString filename=QString::asprintf(":/dice/images/d%d.jpg",mDiceValue);
pic.load(filename);
ui->LabPic->setPixmap(pic);
}
}
void Dialog::on_btnStartThread_clicked()
{
mSeq=0;
threadA.start();
ui->btnStartThread->setEnabled(false);
ui->btnStopThread->setEnabled(true);
ui->btnDiceBegin->setEnabled(true);
ui->btnDiceEnd->setEnabled(false);
}
void Dialog::on_btnDiceBegin_clicked()
{
threadA.diceBegin();
mTimer.start(100); //定时器100读取一次数据
ui->btnDiceBegin->setEnabled(false);
ui->btnDiceEnd->setEnabled(true);
}
void Dialog::on_btnDiceEnd_clicked()
{
threadA.diceEnd();
mTimer.stop();
ui->btnDiceBegin->setEnabled(true);
ui->btnDiceEnd->setEnabled(false);
}
void Dialog::on_btnStopThread_clicked()
{
threadA.stopThread();//结束线程的run()函数执行
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();
}
4. 主函数文件
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}