QT多线程(二)

前言

目的是在主线程中,使用信号和槽来执行一个子线程中的处理函数。

 

  • 当点击start按钮时,子线程每秒钟发射一个信号(mySignal) 并在控制台打印线程地址,主线程接收此信号执行数字累加。
  • 当点击stop按钮时,停止子线程,并释放内存。
  • 当点击关闭窗口按钮时,可能子线程还在运行,此时就要触发stop按钮的信号执行停止子线程。

 

步骤

  1. 创建自定义类Thread继承QObject,并在槽函数中写相应的处理代码。
  2. 在主线程中创建一个Thread的对象myT,和QThread(子线程)的对象thread。
  3. 将myT加入到子线程中。
  4. 启动子线程thread(此时并没有执行myT中的处理函数myTimerout())。
  5. 通过主线程的信号startThread()唤醒子线程的函数myTimerout()。
  6. 子线程中myTimerout()发射信号mySignal(),主线程接收执行dealSignal()。

 

代码:

自定义类Thread:

thread.h

#include<QObject>
#include<QDebug>
#include<QThread>

class Thread : public QObject
{

	Q_OBJECT
public:
	Thread() ;

	void set_flag(bool x) ;

signals:
	void mySignal() ;

public slots:
	void myTimerout();

private:
	bool flag;
};

thread.cpp

#include"thread.h"
#include "QThread"

Thread::Thread()
{
	flag = false ;
}

void Thread::set_flag(bool x)
{
	this->flag = x ;
}

void Thread::myTimerout()
{
	while(!flag)
	{
		for(long long i = 0; i < 500000000; i++) ;

		emit mySignal() ;

		qDebug() << QThread::currentThread() ;
	}
}

 

classwindow.h

#ifndef CLASSWINDOW_H
#define CLASSWINDOW_H

#include <QtGui/QMainWindow>
#include <QDebug>
#include <QThread>
#include "ui_classwindow.h"
#include "thread.h"

class ClassWindow : public QMainWindow
{
	Q_OBJECT

public:
	ClassWindow(QWidget *parent = 0, Qt::WFlags flags = 0);
	~ClassWindow();

private:
	Ui::ClassWindowClass ui;
	Thread *myT;
	QThread *thread ;

signals:
	void startThread() ;

public slots:
	void startButton_licked() ;
	void stopButton_clicked() ;
	//处理子线程发射的信号的函数
	void dealSignal() ;
};

#endif // CLASSWINDOW_H

 

classwindow.cpp

#include "classwindow.h"

ClassWindow::ClassWindow(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	ui.setupUi(this);

	//创建自定义线程类,动态分配空间,不能指定父对象
	myT = new Thread ;

	//创建子线程
	thread = new QThread(this) ;

	//把自定义线程加入到子线程中
	myT->moveToThread(thread) ;

	qDebug() << QThread::currentThread() ;

	//主线程发射信号,子线程接收开始执行函数myTimout()
	QObject::connect(this, SIGNAL(startThread()), myT, SLOT(myTimerout())) ;

	//子线程中的myTimout()每秒发射一个信号,主线程执行dealSignal
	QObject::connect(myT, SIGNAL(mySignal()), this, SLOT(dealSignal()));

	//关闭按钮触发stop按钮来停止子线程
	QObject::connect(this, SIGNAL(destroyed()), this, SLOT(stopButton_clicked())) ;

	//线程处理函数不能操作图形用户界面
}

ClassWindow::~ClassWindow()
{

}



void ClassWindow::startButton_licked()
{
	if(thread->isRunning())
		return ;

	myT->set_flag(false) ;
	thread->start() ;
	emit startThread() ;
}

void ClassWindow::stopButton_clicked()
{
	if(thread->isFinished())
		return ;

	myT->set_flag(true) ;
	thread->quit() ;
	thread->wait() ;

	delete myT ;
}

void ClassWindow::dealSignal()
{
	static int i = 0;
	i++;
	ui.lcdNumber->display(i) ;
}

 

运行时可以看到,控制台上显示的主线程和子线程不是一个地址。

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值