当前位置:   article > 正文

Qt GUI程序中单线程和多线程的区别_qt 插件是独立的线程吗

qt 插件是独立的线程吗

转载:https://blog.csdn.net/hulifangjiayou/article/details/50170739

转载:https://www.cnblogs.com/flowingwind/p/8361939.html#3930874

Qt应用程序exec后就会生成一个线程,这个线程就是主线程,在GUI程序中也称为GUI线程。主线程也是唯一允许创建QApplication或QCoreAppliation对象,比并且可以对创建的对象调用exec()的线程,从而进入事件循环。 
在只有主线程即单线程的情况中,每一个事件的发生都需要进入事件循环进行等待,如有在某一步计算量比较大,则会一直占用CPU不放,导致其它操作无法完成,界面陷入冻结状态,例如像下面的情况: 
在主界面中有两个按钮,其中一个按钮用于一个非常大的计算并在结束的显示结果,另外一个按钮用于显示文本“hello, world!”。代码如下: 
mainwindow.h:

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. namespace Ui {
  5. class MainWindow;
  6. }
  7. class MainWindow : public QMainWindow
  8. {
  9. Q_OBJECT
  10. public:
  11. explicit MainWindow(QWidget *parent = 0);
  12. ~MainWindow();
  13. private slots:
  14. void on_calculationButton_clicked();
  15. void on_displayButton_clicked();
  16. private:
  17. Ui::MainWindow *ui;
  18. };
  19. #endif // MAINWINDOW_H

mainwindow.cpp:

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include <QString>
  4. MainWindow::MainWindow(QWidget *parent) :
  5. QMainWindow(parent),
  6. ui(new Ui::MainWindow)
  7. {
  8. ui->setupUi(this);
  9. }
  10. MainWindow::~MainWindow()
  11. {
  12. delete ui;
  13. }
  14. void MainWindow::on_calculationButton_clicked() //计算
  15. {
  16. int result = 0;
  17. for(int i = 0; i < 2000000000; i++)
  18. result += i;
  19. ui->displayEdit->setText(QString::number(result));
  20. }
  21. void MainWindow::on_displayButton_clicked() //单击显示文本
  22. {
  23. static int flag = 0;
  24. if(flag == 0)
  25. {
  26. flag = 1;
  27. ui->displayEdit->setText(tr("hello, world!"));
  28. }
  29. else
  30. {
  31. flag = 0;
  32. ui->displayEdit->setText(tr("I Love You!"));
  33. }
  34. }

结果: 
这里写图片描述

可以看到,在点击计算按钮之后,进入计算,界面被冻结住了,如果在点击窗口上的其它按钮,则无法反映。 
对于这种超大计算量的操作,我们将其分离出去单独处理,处理好了在跟主界面反馈一个结果即可,像这种情况就需要为主线程另外开辟一个新的线程来处理计算,并且在计算结束的时候与主线程通信,反馈结果。反馈结果需要一个同步操作,而Qt中的signal/slot正好能够满足这个要求,于是,我们将计算操作放到另外一个线程中进行,然后将计算结果通过一个signal传递到主线程中的一个slot,从而实现了与主线程之间的通信。代码修改如下: 
mainwindow.h:

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. class Thread;
  5. namespace Ui {
  6. class MainWindow;
  7. }
  8. class MainWindow : public QMainWindow
  9. {
  10. Q_OBJECT
  11. public:
  12. explicit MainWindow(QWidget *parent = 0);
  13. ~MainWindow();
  14. private slots:
  15. void on_calculationButton_clicked(); //计算按钮
  16. void on_displayButton_clicked(); //显式按钮
  17. void displayResult(int);
  18. private:
  19. Ui::MainWindow *ui;
  20. Thread *thread;
  21. };
  22. #endif // MAINWINDOW_H

thread.h:

  1. #ifndef THREAD_H
  2. #define THREAD_H
  3. #include <QThread>
  4. class Thread : public QThread{
  5. Q_OBJECT
  6. public:
  7. Thread(); //构造函数
  8. signals:
  9. void returnResult(int);
  10. protected:
  11. void run();
  12. };
  13. #endif // THREAD_H

mainwindow.cpp:

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include <QString>
  4. #include "thread.h"
  5. MainWindow::MainWindow(QWidget *parent) :
  6. QMainWindow(parent),
  7. ui(new Ui::MainWindow)
  8. {
  9. ui->setupUi(this);
  10. thread = new Thread();
  11. connect(thread, SIGNAL(returnResult(int)), this, SLOT(displayResult(int)));
  12. }
  13. MainWindow::~MainWindow()
  14. {
  15. delete ui;
  16. }
  17. void MainWindow::on_calculationButton_clicked() //计算
  18. {
  19. thread->start();
  20. }
  21. void MainWindow::on_displayButton_clicked() //单击显示文本
  22. {
  23. static int flag = 0;
  24. if(flag == 0)
  25. {
  26. flag = 1;
  27. ui->displayEdit->setText(tr("hello, world!"));
  28. }
  29. else
  30. {
  31. flag = 0;
  32. ui->displayEdit->setText(tr("I Love You!"));
  33. }
  34. }
  35. void MainWindow::displayResult(int result)
  36. {
  37. ui->displayEdit->setText(QString::number(result));
  38. }

thread.cpp:

  1. #include "thread.h"
  2. Thread::Thread()
  3. {
  4. //
  5. }
  6. void Thread::run()
  7. {
  8. int result = 0;
  9. for(int i = 0; i < 2000000000; i++)
  10. result += i;
  11. emit returnResult(result); //将结果放在信号中
  12. }

运行结果如下: 
这里写图片描述

可以看到,在点击计算按钮之后,在点击显示文本按钮仍然可以得到结果。在另外一个线程中计算结束后,便会改变主线程中的显示结果。 
这里写图片描述

总结:当主线程需要另外一个线程提供服务,需要另外一个线程中的计算结果来修改主线程中的某个控件状态或内容。我们可以为这些超级复杂的任务开辟一个新的线程,在这个线程中执行任务,然后将执行结果通过一个signal来传递给主线程,如果有输出则可以通过signal的参数传递,如果仅仅只需要一个信号则不需要参数。

单线程Qt源码:https://download.csdn.net/download/qq_39736982/10680542

多线程Qt源码: https://download.csdn.net/download/qq_39736982/10680553

建议使用的线程编写模板:https://download.csdn.net/download/qq_39736982/10685993

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/854119
推荐阅读
相关标签
  

闽ICP备14008679号