您好,欢迎来到华佗小知识。
搜索
您的当前位置:首页QtQThread线程创建,线程同步,线程通信实例

QtQThread线程创建,线程同步,线程通信实例

来源:华佗小知识
QtQThread线程创建,线程同步,线程通信实例

1. 继承QThread, 实现run()⽅法, 即可创建线程。

2. 实例1 代码myThread.h

#ifndef MYTHREAD_H#define MYTHREAD_H#include

class myThread : public QThread //myThread 线程类{

Q_OBJECT

public:

myThread();

void setMessage(const QString &message); void stop();protected:

void run(); //复写run()⽅法,⾥⾯是线程 的 主体代码private:

QString messageStr; volatile bool stopped;};

#endif // MYTHREAD_H

myThread.cpp

#include \"myThread.h\"#include myThread::myThread(){

stopped = false;}

void myThread::run() //实现run()⽅法, 隔1秒输出messageStr{

while(!stopped) {

qDebug() << messageStr << endl; sleep(1); }

stopped = false;}

void myThread::stop(){

stopped = true;}

void myThread::setMessage(const QString &message){

messageStr = message;}

dialog.h

#ifndef DIALOG_H#define DIALOG_H#include #include

#include \"myThread.h\"class Dialog : public QDialog{

Q_OBJECT public:

Dialog(QWidget *parent = 0); ~Dialog();protected:

void closeEvent(QCloseEvent *event);private slots:

void startOrStopThreadA(); void startOrStopThreadB();

private:

myThread threadA; //⽤线程类 实例化 线程对象 myThread threadB;

QPushButton *threadAButton; QPushButton *threadBButton; QPushButton *quitButton;};

#endif // DIALOG_H

dialog.cpp

#include \"dialog.h\"

Dialog::Dialog(QWidget *parent) : QDialog(parent){

threadA.setMessage(\"A\"); threadB.setMessage(\"B\");

threadAButton = new QPushButton(tr(\"Start A\")); threadBButton = new QPushButton(tr(\"Start B\")); quitButton = new QPushButton(tr(\"Quit\")); quitButton->setDefault(true);

connect(threadAButton, SIGNAL(clicked()), this, SLOT(startOrStopThreadA())); connect(threadBButton, SIGNAL(clicked()), this, SLOT(startOrStopThreadB())); connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); QHBoxLayout *hLayout = new QHBoxLayout; hLayout->addWidget(threadAButton); hLayout->addWidget(threadBButton); hLayout->addWidget(quitButton); setLayout(hLayout);}

Dialog::~Dialog(){ }

void Dialog::startOrStopThreadA(){

if( threadA.isRunning() ) {

threadA.stop(); //结束线程

threadAButton->setText(tr(\"Start A\")); } else {

threadA.start(); //thread.start()开始线程 threadAButton->setText(tr(\"Stop A\")); }}

void Dialog::startOrStopThreadB(){

if( threadB.isRunning() ) {

threadB.stop();

threadBButton->setText(tr(\"Start B\")); } else {

threadB.start();

threadBButton->setText(tr(\"Stop B\")); }}

void Dialog::closeEvent(QCloseEvent *event) //当⽤户点击quit按键 或 这退出UI的时候,回调closeEvent函数{

threadA.stop(); threadB.stop(); threadA.wait(); threadB.wait(); event->accept(); //qDebug(\"--log--\");}

3. 线程同步

QT线程同步的类有: QMutex, QReadWriteLock, QSemaphore, QWaitcondition.QMutext互斥锁: 可以锁住⼀段代码,同⼀时间只能有⼀个线程访问。

或者⽤简化锁QMutexLocked类, 构造函数输⼊QMutex并将其锁住, 析构函数将其解锁。

QReadWriteLock类, 允许多个线程读共享资源,但是只允许⼀个线程写共享资源。

QSemaphore 信号量 互斥量, 解决 ⽣产者--消费者 问题

4. 利⽤信号槽, 主线程和⼦线程通信,互相发送消息。

⼦线程向主线程发送 每隔⼀秒向主线程发送累加数字, 主线程按键信息发送到⼦线程。。Thread.h

#ifndef THREAD_H#define THREAD_H#include

class Thread : public QThread{

Q_OBJECTprivate:

int number;protected: void run();public:

Thread(QObject *parent=0); ~Thread();signals:

void UpdateSignal(int num);public slots:

void ResetSlot();};

#endif // THREAD_H

Thread.cpp

#include \"Thread.h\"

Thread::Thread(QObject *parent){

number = 0;}

Thread::~Thread(){}

void Thread::run(){

while(1) {

emit UpdateSignal(number); //发送更新信号给主线程,附带参数number number++; sleep(1); }}

void Thread::ResetSlot(){

number = 0;

emit UpdateSignal(number); //发送重置number信号}

widget.h

#ifndef WIDGET_H#define WIDGET_H#include #include \"Thread.h\"

class Widget : public QWidget{

Q_OBJECT public:

Widget(QWidget *parent = 0); ~Widget();

private:

QLabel *label;

QPushButton *startButton; QPushButton *stopButton; QPushButton *resetButton; Thread *myThread; int number;signals:

void ResetSignal();public slots:

void clearSlot(); void startSlot(); void stopSlot();

void updateSlot(int num);};

#endif // WIDGET_H

widget.cpp

#include \"widget.h\"

Widget::Widget(QWidget *parent) : QWidget(parent){

startButton = new QPushButton(\"start\"); stopButton = new QPushButton(\"stop\"); resetButton = new QPushButton(\"reset\"); label = new QLabel(\"empty\"); myThread = new Thread();

QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(label);

layout->addWidget(startButton); layout->addWidget(stopButton); layout->addWidget(resetButton); setLayout(layout);

connect(stopButton, SIGNAL(clicked()), this, SLOT(stopSlot())); connect(startButton, SIGNAL(clicked()), this, SLOT(startSlot())); connect(resetButton, SIGNAL(clicked()), this, SLOT(clearSlot()));

connect(myThread, SIGNAL(UpdateSignal(int)), this, SLOT(updateSlot(int))); //⼦线程发信号给主线程,更新number connect(this, SIGNAL(ResetSignal()), myThread, SLOT(ResetSlot())); //主线程发信号给⼦线程,重置number信号 resize(200, 200);}

Widget::~Widget(){ }

void Widget::startSlot(){

myThread->start();}

void Widget::stopSlot(){

myThread->terminate();}

void Widget::updateSlot(int num){

label->setText(QString::number(num));}

void Widget::clearSlot(){

emit ResetSignal(); //主线程发送重置信号 给 ⼦线程}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo0.cn 版权所有 湘ICP备2023017654号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务