在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();
}
效果如下:
还有一种方法是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);
}
运行结果如下: