基于vs开发的qt项目,基于object的qt多线程的简单应用与理解。

这篇博客详细介绍了如何在Qt环境中利用QThread类创建子线程,实现在主线程(GUI)和子线程间的交互,确保在不阻塞用户界面的情况下动态更新QLabel控件的内容。通过信号槽机制,作者展示了如何在按钮点击事件中启动和停止线程,并在子线程中改变label的显示文本。同时,还讨论了直接通过按钮点击和使用信号连接两种方式的适用场景。
摘要由CSDN通过智能技术生成

按照往常先贴运行结果

点击open开关后可以对下方的label控件进行滚动显示,然后点击close后可以关闭线程运行。
直接上代码。
mythread.h

/*子线程程序*/
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <qlabel.h>
class MyThread : public QObject
{
	Q_OBJECT
	
public:
	MyThread(QObject *parent=0);
	~MyThread();
	void change_label_text(QLabel &label_);//定义改变label控件函数
	void change_label_text2(QLabel &label_);
	void setFlag(bool flag = true);//定义flag为布尔变量(布尔变量只能显示true与false两个情况)
	void change_label_text2();
	void setFlag2(bool flag2 = true);

	
signals:
	void mySignal();
	void mySignal2();
private:
	bool isStop;
	bool isStop2;
	bool k;
	bool j;
public:
	bool returnK(){ return this->k; };//执行识别转化
	bool returnj(){ return this->j; };
};

#endif // MYTHREAD_H

reg.h

#ifndef REG_H
#define REG_H
#include <qgroupbox.h>
#include <QtWidgets/QWidget>
#include <QLabel>
#include "mythread.h"
#include <QThread>

class reg : public QWidget
{
	Q_OBJECT

public:
	explicit reg(QWidget *parent = 0);
	~reg();
	void dealDestroy1();
	void dealDestroy2();//定义结束函数

private:
	QGroupBox *GroupBox_1();
	QGroupBox *GroupBox_2();
	QLabel *label_1;
	QLabel *label_2;
private:
	//定义线程
	MyThread *myT;
	QThread *thread;
	MyThread *myT2;
	QThread *thread2;

private slots:
//定义链接函数
	void change_text_start1();
	void change_text_stop1();
	void change_text_start2();
	void change_text_stop2();
signals:
	//定义信号函数
	void startThread();
	void startThread2();
	
};

#endif // REG_H

main.cpp

#include "reg.h"
#include <QtWidgets/QApplication>
#include <QApplication>


int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	reg w;
	w.show();
	return a.exec();
}

mythread.cpp

#pragma execution_character_set("UTF-8")
#include <QThread>
#include <QDebug>
#include <QMessageBox>
#include "reg.h"
#include <QT>
MyThread::MyThread(QObject *parent)
	: QObject(parent)
{
	//初始化变量
	isStop = false;
	isStop2 = false;
}
MyThread::~MyThread()
{
}

void MyThread::change_label_text( QLabel &label_)
{
	while (isStop == false)
	{
		QThread::sleep(1);//延迟1秒
		k = !k;//布尔变量的转化
		emit &MyThread::mySignal;//emit(发出传输信号)
		qDebug() << "子程序信号:" << QThread::currentThread();
		qDebug() << "k:" << k;//在输出是确认是否可以运行
		if (k) {
			label_.setText("sss");//对k进行判断改变label控件文字
		}
		else if (!k)
		{
			label_.setText("aaaaa");
		}

		if (isStop==true)//结束循环
		break;
	}
}
void MyThread::change_label_text2(QLabel &label_)
{
	while (isStop2 == false)
	{
		QThread::sleep(1);
		j = !j;
		emit &MyThread::mySignal2;
		qDebug() << "子程序信号:" << QThread::currentThread();
		qDebug() << "j:" << j;
		if (j) {
			label_.setText("kkk");
		}
		else if (!j)
		{
			label_.setText("bbb");
		}

		if (isStop == true)
		break;
	}
}
//
void MyThread::setFlag(bool flag)
{
	isStop = flag;
}
void MyThread::setFlag2(bool flag2)
{
	isStop2 = flag2;
}

reg.cpp

#pragma execution_character_set("UTF-8")
#include "reg.h"
#include "mythread.h"
#include "QPushButton.h"
#include <QLabel>
#include <QGroupBox>
#include <QGridLayout>
#include <QLayout>
#include <QVBoxLayout>
#include <QWidget>
#include <QDebug>
reg::reg(QWidget *parent)
: QWidget(parent)
{
	//ui界面
	QVBoxLayout *vLayout_1 = new QVBoxLayout;
	QGroupBox *GroupBox_1 = new QGroupBox(QStringLiteral("GroupBox1"));
	QPushButton *button_1 = new QPushButton("open1");
	QPushButton *button_3 = new QPushButton("close1");
	vLayout_1->addWidget(button_1);
	vLayout_1->addWidget(button_3);
	label_1 = new QLabel("label10");
	connect(button_1, SIGNAL(clicked()), this, SLOT(change_text_start1()));//点击按钮使他进入线程开启程序
	connect(button_3, SIGNAL(clicked()), this, SLOT(change_text_stop1()));
	vLayout_1->addWidget(label_1);
	GroupBox_1->setLayout(vLayout_1);

	QVBoxLayout *vLayout_2 = new QVBoxLayout;
	QGroupBox *GroupBox_2 = new QGroupBox(QStringLiteral("GroupBox2"));
	QPushButton *button_2 = new QPushButton("open2");
	QPushButton *button_4 = new QPushButton("close2");
	vLayout_2->addWidget(button_2);
	vLayout_2->addWidget(button_4);
	label_2 = new QLabel("label20");
	connect(button_2, SIGNAL(clicked()), this, SLOT(change_text_start2()));
	connect(button_4, SIGNAL(clicked()), this, SLOT(change_text_stop2()));
	vLayout_2->addWidget(label_2);
	GroupBox_2->setLayout(vLayout_2);

	QHBoxLayout *hlayout_1 = new QHBoxLayout(this);
	hlayout_1->addWidget(GroupBox_1);
	hlayout_1->addWidget(GroupBox_2);
	hlayout_1->addStretch();
	//定义子线程
	myT = new MyThread;//定义myt为mythread.cpp的一个对象
	thread = new QThread;//定义thread为新线程并给与新的内存
	myT->moveToThread(thread);//讲myt对象放入线程中
	connect(this, &reg::startThread, myT, [=]()//接受来自startThread的信号执行程序
	{
		myT->change_label_text(*label_1);//改变label控件,改变指定的label控件
	});
	connect(this, &reg::destroyed, this, &reg::dealDestroy1);
	
	myT2 = new MyThread;
	thread2 = new QThread;
	myT2->moveToThread(thread2);
	connect(this, &reg::startThread2, myT2, [=]()
	{
		myT->change_label_text2(*label_2);
	});
	connect(this, &reg::destroyed, this, &reg::dealDestroy2);
	///
}
reg::~reg()
{
}

void reg::dealDestroy1()
{
	qDebug() << "在执行dealDestroy" << QThread::currentThread();
	change_text_stop1();//关闭线程函数
	delete myT;//删除退出子线程
}
void reg::change_text_start1()
{
	if (thread->isRunning() == true) return;//如果子线程在开启状态则返回空值
	qDebug() << "在执行change_text_start";
	thread->start();//线程开启
	myT->setFlag(false);
	emit startThread();//发出信号
}
void reg::change_text_stop1()
{
	if (thread->isRunning() == false)return;
	myT->setFlag(true);
	thread->quit();//线程关闭清空
	thread->wait();//线程等待(2句话是共同实现的)
}
void reg::dealDestroy2()
{
	qDebug() << "在执行dealDestroy" << QThread::currentThread();
	change_text_stop2();
	delete myT2;
}
void reg::change_text_start2()
{
	if (thread2->isRunning() == true) return;
	thread2->start();
	myT2->setFlag2(false);
	emit startThread2();
}
void reg::change_text_stop2()
{
	if (thread2->isRunning() == false)return;
	myT2->setFlag2(true);
	thread2->quit();
	thread2->wait();
}

应用的关键还是在于建立线程

	myT2 = new MyThread;
	thread2 = new QThread;
	myT2->moveToThread(thread2);

其次是对线程运行的连接

	connect(this, &reg::startThread2, myT2, [=]()
	{
		myT->change_label_text2(*label_2);
	});

当然这些地方不一定需要使用通过信号连接,可以直接通过按钮点击也是可以的,但是在项目中会出现许多奇奇怪怪的问题,所以一般情况下可以使用按钮直接连接,也可以使用信号连接。
这东西根据实际应用来决定吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值