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

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

经验分享 程序员 微信小程序 职场和发展