Qt QThread 线程创建,线程同步,线程通信 实例

来源:互联网 发布:3d图像重建算法 编辑:程序博客网 时间:2024/05/17 08:40

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

 

2. 实例1 代码

myThread.h

#ifndef MYTHREAD_H#define MYTHREAD_H#include <QThread>class myThread : public QThread   //myThread 线程类{    Q_OBJECTpublic:    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 <QDebug>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 <QDialog>#include <QtGui>#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 <QThread>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 <QtGui>#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();     //主线程发送重置信号 给 子线程}



 

原创粉丝点击