#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(); //主线程发送重置信号 给 ⼦线程}