Qt GUI程序中主线程与非主线程之间的通信
来源:互联网 发布:神秘博士 知乎 编辑:程序博客网 时间:2024/05/11 23:54
原文地址:http://blog.csdn.net/hulifangjiayou/article/details/50170739
Qt应用程序exec后就会生成一个线程,这个线程就是主线程,在GUI程序中也称为GUI线程。主线程也是唯一允许创建QApplication或QCoreAppliation对象,比并且可以对创建的对象调用exec()的线程,从而进入事件循环。
在只有主线程即单线程的情况中,每一个事件的发生都需要进入事件循环进行等待,如有在某一步计算量比较大,则会一直占用CPU不放,导致其它操作无法完成,界面陷入冻结状态,例如像下面的情况:
在主界面中有两个按钮,其中一个按钮用于一个非常大的计算并在结束的显示结果,另外一个按钮用于显示文本“hello, world!”。代码如下:
mainwindow.h:
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); ~MainWindow();private slots: void on_calculationButton_clicked(); void on_displayButton_clicked();private: Ui::MainWindow *ui;};#endif // MAINWINDOW_H
mainwindow.cpp:#include "mainwindow.h"#include "ui_mainwindow.h"#include <QString>MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this);}MainWindow::~MainWindow(){ delete ui;}void MainWindow::on_calculationButton_clicked() //计算{ int result = 0; for(int i = 0; i < 2000000000; i++) result += i; ui->displayEdit->setText(QString::number(result));}void MainWindow::on_displayButton_clicked() //单击显示文本{ static int flag = 0; if(flag == 0) { flag = 1; ui->displayEdit->setText(tr("hello, world!")); } else { flag = 0; ui->displayEdit->setText(tr("I Love You!")); }}
结果:
可以看到,在点击计算按钮之后,在点击显示文本按钮仍然可以得到结果。在另外一个线程中计算结束后,便会改变主线程中的显示结果。
这里写图片描述
总结:当主线程需要另外一个线程提供服务,需要另外一个线程中的计算结果来修改主线程中的某个控件状态或内容。我们可以为这些超级复杂的任务开辟一个新的线程,在这个线程中执行任务,然后将执行结果通过一个signal来传递给主线程,如果有输出则可以通过signal的参数传递,如果仅仅只需要一个信号则不需要参数。
可以看到,在点击计算按钮之后,进入计算,界面被冻结住了,如果在点击窗口上的其它按钮,则无法反映。
对于这种超大计算量的操作,我们将其分离出去单独处理,处理好了在跟主界面反馈一个结果即可,像这种情况就需要为主线程另外开辟一个新的线程来处理计算,并且在计算结束的时候与主线程通信,反馈结果。反馈结果需要一个同步操作,而Qt中的signal/slot正好能够满足这个要求,于是,我们将计算操作放到另外一个线程中进行,然后将计算结果通过一个signal传递到主线程中的一个slot,从而实现了与主线程之间的通信。代码修改如下:
mainwindow.h:
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>class Thread;namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); ~MainWindow();private slots: void on_calculationButton_clicked(); //计算按钮 void on_displayButton_clicked(); //显式按钮 void displayResult(int);private: Ui::MainWindow *ui; Thread *thread;};#endif // MAINWINDOW_H
thread.h:
#ifndef THREAD_H#define THREAD_H#include <QThread>class Thread : public QThread{ Q_OBJECTpublic: Thread(); //构造函数signals: void returnResult(int);protected: void run();};#endif // THREAD_H
mainwindow.cpp:
#include "mainwindow.h"#include "ui_mainwindow.h"#include <QString>#include "thread.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this); thread = new Thread(); connect(thread, SIGNAL(returnResult(int)), this, SLOT(displayResult(int)));}MainWindow::~MainWindow(){ delete ui;}void MainWindow::on_calculationButton_clicked() //计算{ thread->start();}void MainWindow::on_displayButton_clicked() //单击显示文本{ static int flag = 0; if(flag == 0) { flag = 1; ui->displayEdit->setText(tr("hello, world!")); } else { flag = 0; ui->displayEdit->setText(tr("I Love You!")); }}void MainWindow::displayResult(int result){ ui->displayEdit->setText(QString::number(result));}
thread.cpp:
#include "thread.h"Thread::Thread(){ //}void Thread::run(){ int result = 0; for(int i = 0; i < 2000000000; i++) result += i; emit returnResult(result); //将结果放在信号中}
运行结果如下:
可以看到,在点击计算按钮之后,在点击显示文本按钮仍然可以得到结果。在另外一个线程中计算结束后,便会改变主线程中的显示结果。
总结:当主线程需要另外一个线程提供服务,需要另外一个线程中的计算结果来修改主线程中的某个控件状态或内容。我们可以为这些超级复杂的任务开辟一个新的线程,在这个线程中执行任务,然后将执行结果通过一个signal来传递给主线程,如果有输出则可以通过signal的参数传递,如果仅仅只需要一个信号则不需要参数。
- Qt GUI程序中主线程与非主线程之间的通信
- Qt GUI程序中主线程与非主线程之间的通信
- Qt的主线程与GUI
- QT中实现Thread与GUI主线程连通方法
- QT中实现Thread与GUI主线程连通方法
- QT中实现Thread与GUI主线程连通方法
- QT中实现Thread于GUI主线程通信的方法
- Qt主线程与子线程之间的信号槽通信
- QT中的多线程-与主线程通信
- androd中主线程和非主线程的通信机制(Handler/Looper/Message)
- Android主线程与子线程之间的通信
- handler 主线程与子线程之间的通信
- Android主线程与子线程之间的通信
- 子线程与主线程之间的通信
- c#子线程与主线程之间的通信
- QT子线程与主线程的信号槽通信
- QT子线程与主线程的信号槽通信
- QT子线程与主线程的信号槽通信
- Python学习04-列表(List)/元祖/字典总结
- android客户端百度云推送的使用总结
- 关于Java虚拟机内存原型介绍
- java数据类型与sql数据类型的对照,如数据库中的char类型对应java中的数据类型为?
- MySQL查询中 find_in_set 在使用中可能遇到的问题
- Qt GUI程序中主线程与非主线程之间的通信
- jsonview浏览器插件 查看格式化json数据
- redis位图法统计活跃用户+统计3天的连续登录用户案例
- C++学习之路C++Primer学习笔记(二)如何选择类型
- JRebel for Android 破解
- Protobuf,从入门到穿拖鞋
- kamailio 启动错误
- 逃避苹果审核,进行强制更新
- 双向可控硅的工作原理