1)问题出现场景:
在公司写了一个自动化库文件生成的工具,大慨就是点击按钮,主函数逻辑执行,从执行的那一刻下方显示已执行时间,但是发现下方LCD部件的时间一直未刷新,槽函数也没有调用
2)问题成因:
主函数逻辑比较慢,需要执行10秒左右,主线程被耗时操作阻塞
3)解决办法
使用多线程 将耗时操作移到工作线程中执行,保持主线程(GUI线程)畅通。
下面大概模拟一下当时的情景:
qt设计师 :有一个按钮 一个LCD部件
点击按钮--> 功能执行 -->计时开始
主窗口类,给按钮和lcd部件添加槽函数
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_TimerTest.h"
#include <QTimer>
#include <QElapsedTimer>
class TimerTest : public QMainWindow
{
Q_OBJECT
public:
TimerTest(QWidget *parent = nullptr);
~TimerTest();
private slots:
void button_clicked();//响应按钮
void updateTime();//刷新时间
private:
Ui::TimerTestClass ui;
QTimer *timer;
QElapsedTimer *elapsedTimer;
};
cpp文件
#include "TimerTest.h"
#include <QPushButton>
#include <QApplication>
#include "otherr.h"
TimerTest::TimerTest(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
timer = new QTimer(this);
elapsedTimer = new QElapsedTimer();
connect(ui.pushButton, &QPushButton::clicked, this, &TimerTest::button_clicked);
connect(timer, &QTimer::timeout, this, &TimerTest::updateTime);
}
TimerTest::~TimerTest()
{
delete timer;
}
void TimerTest::button_clicked()
{
timer->start(1000);//正常每过1s都会调用updateTime,但是因为主线程阻塞,迟迟未调用
elapsedTimer->start();
Other o;
o.run();
}
void TimerTest::updateTime()
{
int iTime = elapsedTimer->elapsed();
ui.lcdNumber->display(iTime / 1000);
}
模拟阻塞主线程
class Other
{
public:
void run();
};
void Other::run()
{
//执行操作 可能会耗时10s
for (int i = 0; i < 10; i++)
{
Sleep(500);
}
}
解决问题后:
修改函数button_clicked
void TimerTest::button_clicked()
{
timer->start(1000);
elapsedTimer->start();
// 使用QtConcurrent在后台线程执行耗时操作
QtConcurrent::run(this,&TimerTest::executeOtherInThread);
}
新增槽函数 executeOtherInThread:
private slots:
void button_clicked();
void updateTime();
void executeOtherInThread();
void TimerTest::executeOtherInThread()
{
Other o;
o.run();
}
不知道丝不丝滑,好在问题解决了,下班....