天天看点

QT子线程更新主线程

在qt中子线程控制ui线程控件刷新,通过查阅资料,用重构qthread方法比较简单,可靠。现在写一个例程以便交流。例程是通过子线程实现ui textEdit中数字刷新。实现如下:

#include "ui_QtTest.h"
#include <qthread.h>
class QtTest : public QMainWindow{
	Q_OBJECT
public:
	QtTest(QWidget *parent = Q_NULLPTR);
 	void stsRefresh();
 	int num;
 private:
    Ui::QtTestClass ui;
}

class newThread : public QThread {
 Q_OBJECT
public:
 	newThread(QtTest *gui);
 	~newThread();
 	void run();
 	QtTest *m_gui;
signals:
 	void newSts();
public slots:
 	void updataSts();
};
           
#include "QtTest.h"
QtTest::QtTest(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    num = 1;
    newThread *p = new newThread(this);
    p->start();
}
void QtTest::stsRefresh() {
 	ui.textEdit->setText(QString::number(num));
 	num = num * 2;
}
newThread::newThread(QtTest *gui) {
 this->m_gui = gui;
 connect(this, SIGNAL(newSts()), this, SLOT(updataSts()));
}
newThread::~newThread() {
 disconnect(this, SIGNAL(newSts()), this, SLOT(updataSts()));
}
void newThread::run() {
 while (true) {
  emit newSts();
  msleep(500);
 }
}
void newThread::updataSts() {
 m_gui->stsRefresh();
}
           

效果如下:

QT子线程更新主线程

还有一种方法是moveToThread,官方推荐这种方法。主要是需要新建一个类来实现多线程操作,还要注意主线程和子线程的信号槽交互,(需要主线程和子线程有相互的信号槽)主要是子线程的开启需要主线程的信号,同时主线程的数据更新需要子线程来操作。

新建一个Work类用来实现数据的更新。

#pragma once
#include "qobject.h"
#include <qvector.h>
#include "qthread.h"
#include "qdebug.h"

class Work : public QObject
{
	Q_OBJECT
public: explicit Work(QObject *parent = nullptr);
	QVector<QString> strlist; //更新数据
signals:
	void Ready(QVector<QString> list); //向主线程发送数据信号
public slots:
	void doWork();//接收主线程信号的槽,也是实现线程的主要方法。
};
           

CPP文件

#include "Work.h"

Work::Work(QObject *parent) {
}
void Work::doWork() {
	qDebug() << "run here";
	while (1) {
		strlist.clear();
		for (int i = 0; i < 100; i++) {
			QString str = "str = " + QString::number(i);
			strlist.push_back(str);
		}
		emit Ready(strlist);
		QThread::msleep(500);
	}	
}
           

主函数如下:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_TE.h"
#include "qthread.h"
#include "Work.h"
#include "qstandarditemmodel.h"
#include <QMetaType>

class TE : public QMainWindow
{
	Q_OBJECT
		QThread workThread;		//线程对象
public:
    TE(QWidget *parent = Q_NULLPTR);
	~TE();
public slots:
	void Recive(QVector<QString> list);	//接收子线程数据的槽
private:
    Ui::TEClass ui;
	QStandardItemModel *listModel;
signals:
	void RunWork();		//发送子线程的信号
};
           

CPP文件

#include "TE.h"

TE::TE(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    
qRegisterMetaType<QVector<QString> >("QVector<QString>");

	listModel = new QStandardItemModel(this);
	
	Work *work = new Work;
	work->moveToThread(&workThread);
		
	connect(this, &TE::RunWork, work, &Work::doWork);
	connect(work, &Work::Ready, this, &TE::Recive);
	workThread.start();	//多线程开启
	emit RunWork();	//发送子线程信号
}

TE::~TE() {
	if (workThread.isRunning()) {
		workThread.quit();
		workThread.wait();
	}
	//delete ui;
}

void TE::Recive(QVector<QString> list) {
	listModel->clear();
	for (int i = 0; i < list.size(); i++) {
		QStandardItem *item = new QStandardItem(list[i]);
		listModel->appendRow(item);
	}
	ui.listView->setModel(listModel);
}
           

运行结果如下:

QT子线程更新主线程

继续阅读