【Qt】 Qt中实时更新UI程序示例 |
您所在的位置:网站首页 › qt界面更新 › 【Qt】 Qt中实时更新UI程序示例 |
00. 目录
文章目录 00. 目录 01. 概述 02. 开发环境 03. 实时更新UI(非信号与槽) 04. 实时更新UI(信号与槽) 05. 源码下载 06. 附录 01. 概述 Qt在运行时会开启一个主线程,如果没有开启工作线程的话,所有界面上的操作都是在主线程,包括更新界面或者处理数据等操作。我们都知道如果处理数据比较多的话,最好是在单独开启一个线程来处理数据,这样就不会影响主线程的运行。 02. 开发环境Windows系统:Windows10 Qt版本:Qt5.15或者Qt6 03. 实时更新UI(非信号与槽)QT中不建议工作线程中更新界面。 workthread.h #ifndef WORKTHREAD_H #define WORKTHREAD_H #include class MainWindow; class QLabel; class WorkThread : public QThread { Q_OBJECT public: WorkThread(QObject *parent); ~WorkThread(); void setObject(MainWindow *obj); void setLabel(QLabel *l); void stop(); protected: void run(); private: MainWindow *mainObject = nullptr; QLabel *label = nullptr; int i = 0; volatile bool stopped = false; }; #endif // WORKTHREAD_Hworkthread.cpp #include "workthread.h" #include "mainwindow.h" #include #include WorkThread::WorkThread(QObject *parent):QThread(parent) { stopped = false; } WorkThread::~WorkThread() { } void WorkThread::setObject(MainWindow *obj) { mainObject = obj; } void WorkThread::setLabel(QLabel *l) { label = l; } void WorkThread::run() { qDebug() runInThread(); label->setText(QString("当前计数为:%1").arg(i)); } //下次启动 stopped = false; } //暂停线程 void WorkThread::stop() { stopped = true; qDebug() setupUi(this); thread = new WorkThread(this); thread->setObject(this); thread->setLabel(ui->label); ui->pushButton->setEnabled(true); ui->pushButton_2->setEnabled(false); } MainWindow::~MainWindow() { delete ui; } void MainWindow::runInThread() { count++; ui->label->setText(QString("当前计数为: %1").arg(count)); } //启动线程 void MainWindow::on_pushButton_clicked() { if (nullptr != thread) { thread->start(); } ui->pushButton->setEnabled(false); ui->pushButton_2->setEnabled(true); } //暂停线程 void MainWindow::on_pushButton_2_clicked() { if (nullptr != thread) { thread->stop(); } ui->pushButton->setDisabled(false); ui->pushButton_2->setDisabled(true); }主界面 workthread.h #ifndef WORKTHREAD_H #define WORKTHREAD_H #include class MainWindow; class QLabel; struct Student { int id; char sex; QString name; }; //声明元类型 Q_DECLARE_METATYPE(Student) class WorkThread : public QThread { Q_OBJECT public: WorkThread(QObject *parent); ~WorkThread(); void stop(); protected: void run(); signals: void sigCount(Student s); private: int i = 0; volatile bool stopped = false; }; #endif // WORKTHREAD_Hworkthread.cpp #include "workthread.h" #include "mainwindow.h" #include #include WorkThread::WorkThread(QObject *parent):QThread(parent) { //注册自定义类型 qRegisterMetaType(); stopped = false; } WorkThread::~WorkThread() { } void WorkThread::run() { qDebug() pushButton->setEnabled(true); ui->pushButton_2->setEnabled(false); connect(thread, &WorkThread::sigCount, this, &MainWindow::slotSetValue); } MainWindow::~MainWindow() { delete ui; } //启动线程 void MainWindow::on_pushButton_clicked() { if (nullptr != thread) { thread->start(); } ui->pushButton->setEnabled(false); ui->pushButton_2->setEnabled(true); } //暂停线程 void MainWindow::on_pushButton_2_clicked() { if (nullptr != thread) { thread->stop(); } ui->pushButton->setDisabled(false); ui->pushButton_2->setDisabled(true); } //槽函数 void MainWindow::slotSetValue(Student( s)) { ui->label->setText(QString("当前值为: %1 %2 %3").arg(s.id).arg(s.sex).arg(s.name)); }主界面 【温馨提示】 如果要在Qt信号槽中使用自定义类型,需要注意使用qRegisterMetaType对自定义类型进行注册,当然在不跨线程时使用自定义类型signal/slot来传递,可能不会出现什么问题;一旦涉及跨线程就很容易出错,回想下信号槽的作用就是用来对象与对象之间通信的,难免会跨线程,建议在使用自定义类型利用信号槽通信时,最好先通过qRegisterMetaType()将自定义类型进行注册,以免出错。 总结qRegisterMetaType使用方法如下:1、注册位置:在第一次使用此类链接跨线程的signal/slot之前,一般在当前类的构造函数中进行注册;2、注册方法:在当前类的顶部包含:#include ,构造函数中加入代码:qRegisterMetaType(“Myclass”);3、Myclass的引用类型需单独注册:qRegisterMetaType(“Myclass&”); 05. 源码下载 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |