Qt主线程和工作线程更新界面问题

8 篇文章 0 订阅

Qt在运行时会开启一个主线程,如果没有开启工作线程的话,所有界面上的操作都是在主线程,包括更新界面或者处理数据等操作。大家都知道如果处理数据比较多的话,最好是在单独开启一个线程来处理数据,这样就不会影响主线程的运行。如果在工作线程中更新界面,会如何呢?

线程类:

#pragma once

#include <QThread>
class QtGuiMainThread;

class ThreadTest : public QThread {
	Q_OBJECT

public:
	ThreadTest(QObject *parent);
	~ThreadTest();

	void setObj(QtGuiMainThread* obj);

protected:
	void run();
private:
	QtGuiMainThread* guiMain = nullptr;
};

#include "ThreadTest.h"
#include "QtGuiMainThread.h"

ThreadTest::ThreadTest(QObject *parent)
: QThread(parent) {
}

ThreadTest::~ThreadTest() {
}

void ThreadTest::setObj(QtGuiMainThread* obj) {
	guiMain = obj;
}

void ThreadTest::run() {
	while (true) {
		msleep(1);
		guiMain->runInThread();
	}
}


主界面:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_QtGuiMainThread.h"
class ThreadTest;

class QtGuiMainThread : public QMainWindow {
	Q_OBJECT

public:
	QtGuiMainThread(QWidget *parent = Q_NULLPTR);

	void runInThread();
private slots:
	void slotBtnStartThread();
private:
	Ui::QtGuiMainThreadClass ui;
	ThreadTest* thread = nullptr;
	int cnt = 0;
};


#include "QtGuiMainThread.h"
#include "ThreadTest.h"

QtGuiMainThread::QtGuiMainThread(QWidget *parent)
: QMainWindow(parent) {
	ui.setupUi(this);

	thread = new ThreadTest(this);
	thread->setObj(this);

	connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(slotBtnStartThread()));
}

void QtGuiMainThread::slotBtnStartThread() {
	if (thread != nullptr){
		thread->start();
	}
}

void QtGuiMainThread::runInThread() {
	cnt++;
	ui.label->setText(QStringLiteral("当前计数:%1").arg(cnt));
}

这里写图片描述
点击按钮【开始】启动线程,程序出现了崩溃:
这里写图片描述

说明QT不允许工作线程中更新界面!

那就修改一下代码,通过信号槽的方式更新界面
主界面:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_QtGuiMainThread.h"
class ThreadTest;
class QCloseEvent;

class QtGuiMainThread : public QMainWindow {
	Q_OBJECT

public:
	QtGuiMainThread(QWidget *parent = Q_NULLPTR);

	void runInThread();

	void closeEvent(QCloseEvent *event);
signals:
	void sigCount();
private slots:
	void slotBtnStartThread();
	void slotCount();

private:
	Ui::QtGuiMainThreadClass ui;
	ThreadTest* thread = nullptr;
	int cnt = 0;
};


#include "QtGuiMainThread.h"
#include "ThreadTest.h"

QtGuiMainThread::QtGuiMainThread(QWidget *parent)
: QMainWindow(parent) {
	ui.setupUi(this);

	thread = new ThreadTest(this);
	thread->setObj(this);

	connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(slotBtnStartThread()));
	connect(this, SIGNAL(sigCount()), this, SLOT(slotCount()));
}

void QtGuiMainThread::slotBtnStartThread() {
	if (thread != nullptr){
		thread->start();
	}
}

void QtGuiMainThread::runInThread() {
	emit sigCount();
}

void QtGuiMainThread::slotCount() {
	cnt++;
	ui.label->setText(QStringLiteral("当前计数:%1").arg(cnt));
}

void QtGuiMainThread::closeEvent(QCloseEvent *event) {
	if (thread->isRunning()) {
		thread->terminate();
		thread->quit();
	}
	
}

然后运行一下:
程序能够正常运行,以上!

aaa

评论 14 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:创作都市 设计师:CSDN官方博客 返回首页

打赏作者

wb175208

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值