qt messagebox退出程序_Qt多线程创建
【为什么要用多线程?】
传统的图形用户界面应用程序都只有一个执行线程,并且一次只执行一个操作。如果用户从用户界面中调用一个比较耗时的操作,当该操作正在执行时,用户界面通常会冻结而不再响应。这个问题可以用事件处理和多线程来解决。
【使用多线程有什么好处?】
提高应用程序的响应速度。这对于开发图形界面程序尤其重要,当一个操作耗时很长时(比如大批量I/O或大量矩阵变换等CPU密集操作),整个系统都会等待这个操作,程序就不能响应键盘、鼠标、菜单等操作,而使用多线程技术可将耗时长的操作置于一个新的线程,从而避免上述问题。
使多CPU系统更加有效。当线程数不大于CPU数目时,操作系统可以调度不同的线程运行于不同的CPU上。
改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为独立或半独立的运行部分,这样有利于程序的理解和维护。
【Qt中创建线程的方法】
只需要子类化QThread并重新实现它的run()函数就可以了。run()是个纯虚函数,是线程执行的入口,在run()里出现的代码将会在另外线程中被执行。run()函数是通过start()函数来实现调用的。
【实例】
下面一个例子给出了在应用程序中除了主线程外,还提供了线程A和B。如果单击窗口中的按钮“Start A”,Qt的控制台就会连续输出字母“A”,此时按钮“Start A”被刷新为“Stop A”。再单击按钮“Start B”,控制台会交替输出字母“A”和“B”。如果再单击按钮“Stop A”,则控制台只输出字母“B”。如下图所示:
thread.h代码
#ifndef THREAD_H #define THREAD_H #include #include class Thread : public QThread { Q_OBJECT public: Thread(); void setMessage(QString message); void stop(); protected: void run(); void printMessage(); private: QString messageStr; volatile bool stopped; }; #endif // THREAD_H
注:
stopped被声明为易失性变量(volatile variable,断电或中断时数据丢失而不可再恢复的变量类型),这是因为不同的线程都需要访问它,并且我们也希望确保它能在任何需要的时候都保持最新读取的数值。如果省略关键字volatile,则编译器就会对这个变量的访问进行优化,可能导致不正确的结果。
thread.cpp代码
#include "thread.h" #include Thread::Thread() { stopped = false; } void Thread::run() { while(!stopped) { printMessage(); } stopped = false; } void Thread::stop() { stopped = true; } void Thread::setMessage(QString message) { messageStr = message; } void Thread::printMessage() { qDebug()< sleep(1); }
注:
QTread提供了一个terminate()函数,该函数可以再一个线程还在运行的时候就终止它的执行,但不推荐用terminate(),因为terminate()不会立刻终止这个线程,该线程何时终止取决于操作系统的调度策略,也就是说,它可以随时停止线程执行而不给这个线程自我清空的机会。更安全的方法是用stopped变量和stop()函数,如例子所示。
调用setMessage()让第一个线程每隔1秒打印字母“A”,而让第二个线程每隔1秒打印字母“B”。
线程会因为调用printf()而持有一个控制I/O的锁,多个线程同时调用printf()在某些情况下回造成控制台输出阻塞,而用qDebug()作为控制台输出一般不会出现上述问题。
threaddialog.h代码
#ifndef THREADDIALOG_H #define THREADDIALOG_H #include #include #include #include "thread.h" class ThreadDialog : public QDialog { Q_OBJECT public: ThreadDialog(QWidget *parent=0); protected: void closeEvent(QCloseEvent *event); private slots: void startOrStopThreadA(); void startOrStopThreadB(); void close(); private: Thread threadA; Thread threadB; QPushButton *threadAButton; QPushButton *threadBButton; QPushButton *quitButton; }; #endif // THREADDIALOG_H
threaddialog.cpp代码
#include "threaddialog.h" ThreadDialog::ThreadDialog(QWidget *parent) : QDialog(parent) { threadA.setMessage("A"); threadB.setMessage("B"); threadAButton = new QPushButton(tr("Start A"), this); threadAButton->setGeometry(10, 30, 80, 30); threadBButton = new QPushButton(tr("Start B"),this); threadBButton->setGeometry(110, 30, 80, 30); quitButton = new QPushButton(tr("Quit"), this); quitButton->setGeometry(210, 30, 80, 30); quitButton->setDefault(true); connect(threadAButton, SIGNAL(clicked()), this, SLOT(startOrStopThreadA())); connect(threadBButton, SIGNAL(clicked()), this, SLOT(startOrStopThreadB())); connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); } void ThreadDialog::startOrStopThreadA() { if(threadA.isRunning()) { threadAButton->setText(tr("Stop A")); threadA.stop(); threadAButton->setText(tr("Start A")); } else { threadAButton->setText(tr("Start A")); threadA.start(); threadAButton->setText(tr("Stop A")); } } void ThreadDialog::startOrStopThreadB() { if(threadB.isRunning()) { threadBButton->setText(tr("Stop B")); threadB.stop(); threadBButton->setText(tr("Strat B")); } else { threadBButton->setText(tr("Start B")); threadB.start(); threadBButton->setText(tr("Stop B")); } } void ThreadDialog::closeEvent(QCloseEvent *event) { threadA.stop(); threadB.stop(); threadA.wait(); threadB.wait(); event->accept(); } void ThreadDialog::close() { exit(0); }
注:
startOrStopA的逻辑是:当单击A的按钮时,如果系统判断到有线程A在运行中,就把A的按钮刷新为“Stop A”,表示可以进行stop A的动作,并停止线程A的运行,再将A的按钮刷新为“Start A”。否则,如果线程A没有运行,就把按钮刷新为表示可以运行的“Start A”,启动线程A,然后将A按钮刷新为“Stop A”。
当不用Qt设计器时,new一个button出来,需要指定一个父类,比如this,否则运行程序,窗口里没有按钮。
new了多个按钮或控件,需要用setGeometry来确定它们的大小和位置,否则前面的被后面的覆盖,最终看到的是最后一个按钮。setGeometry的前2个参数是相对于窗口的坐标位置,后两个参数是按钮的长宽。
单击Quit或关闭窗口,就停止所有正在运行的线程,并且在调用函数QCloseEvent::accept()之前等待它们完全结束,这样就可以确保应用程序是以一种原始清空的状态退出的。
如果没有62~65行的重新定义close函数,使进程完全退出。否则点击Quit按钮或叉号退出窗口后,进程依然驻留在系统里。
main.cpp代码
#include "threaddialog.h" #include int main(int argc, char *argv[]){ QApplication app(argc, argv); ThreadDialog *threaddialog = new ThreadDialog; threaddialog->exec(); return app.exec(); }
注:
在GUI程序中,主线程也被称为GUI线程,因为它是唯一一个允许执行GUI相关操作的线程。必须在创建一个QThread之前创建QApplication对象。
运行结果:
项目百度网盘瞎咋链接:
https://pan.baidu.com/s/1N-3NsA41R7Laq9cfSFc9Ew
提取码: 43rb
qt messagebox退出程序_Qt多线程创建相关推荐
- qt 子窗口写到线程就卡死_Qt多线程创建
[为什么要用多线程?] 传统的图形用户界面应用程序都只有一个执行线程,并且一次只执行一个操作.如果用户从用户界面中调用一个比较耗时的操作,当该操作正在执行时,用户界面通常会冻结而不再响应.这个问题可以 ...
- qt messagebox退出程序_[Qt] Mac平台安装最新版qt的方法(源码编译) - 刘傲天
安装方式 安装方式有在线(online)和离线(offline)两个选项,因为在线安装可能要连接国外的服务器非常慢,还会经常失败,所以我们选择离线安装(offline). 选择安装方式 打开https ...
- qt messagebox退出程序_删除英雄联盟LOL电视台,QT语音直播,TP安全中心
大家都知道腾讯游戏都会有各种捆绑安装,与游戏本不相干的程序,还有一些是不断增加的更新文件,这些都要定期清理,能提高游戏运行质量,提高FPS,减少网络延迟.丢包率.这里需要提醒的是,使用wegame平台 ...
- QT 多线程创建方法及应用实例
QT 多线程创建方法及应用实例 方法一: (1)创建一个QT应用 (2)创建线程类,继承QThread simplethreadone.h #ifndef SIMPLETHREADONE_H #def ...
- Qt中另一种创建线程的方式
文章目录 1 Qt中另一种创建线程的方式 1.1 另一种创建线程的方式 1.2 同步型线程的设计 1.3 异步型线程的设计 1 Qt中另一种创建线程的方式 1.1 另一种创建线程的方式 历史的痕迹: ...
- Qt的Tcp服务器多线程编程-附带代码展示
Qt的Tcp服务器多线程编程-附带代码展示 该程序主要实现tcp服务器如何使用多线程的方式来连接多个客户端,此文章没有实现客户端的多线程编程. 创建子线程时需要注意的点: 1.子线程与主线程之间交互数 ...
- 在Qt中使用C++代码创建界面
好儿郎~志在四方 Qt视频教程地址:http://space.bilibili.com/84360636/#!/index 目录视图 摘要视图 订阅 图灵赠书--程序员11月书单 [思考]Pyt ...
- 使用QT SDK 1.1 Qt Creator 2.0.9创建symbian sisx安装包
使用QT SDK 1.1 Qt Creator 2.0.9创建symbian sisx安装包 目前最新(文章记录时刻)的QT SDK 1.1相较于原1.0版本创建symbian sisx安装包非常的不 ...
- Android 多线程创建
Android多线程创建,两种方式 1.继承Thread类 2.实现Runable接口 这两种属于Java多线程的创建,这里不做总结.下面总结一下两种的区别: 继承Thread类,属于继承,存在缺陷, ...
- Python3进阶--Socket编程、多线程(创建方式、线程通信、线程锁、线程池)
第一章 变量.常用循环体.代码结构.代码练习 第二章 列表.元组等数据结构.字符串驻留机制及字符串格式化操作 第三章 函数.面向对象.文件操作.深浅拷贝.模块.异常及捕获 第四章 项目打包.类和对象高 ...
最新文章
- 秒懂 CountDownLatch 与 CyclicBarrier 使用场景
- python中字典和集合的区别_Python中字典和集合学习小结
- Oracle PL/SQL语言入门
- mysql 算子 谓词_[SQL] SQL 基础知识梳理(六)- 函数、谓词、CASE 表达式
- SpringBoot入门详解源码分析
- 工业机械类企业官网织梦模板源码
- java反编译工具_推荐Java反编译工具luyten、jd-gui
- QtCreator 编译时提示 warning C4819 的解决办法
- 帝国理工 计算机 金融和管理,计算机毕业生同样研读帝国理工金融工程
- ubuntu skill
- 桌面被关闭,如何在任务管理器中打开桌面?
- 最安全的邮箱大全排名,公司安全邮箱申请如何设置?
- 用python画漂亮的网状几何图形
- 绝对实践,教你如何成功修改捕鱼达人ipad版 金币
- OpenGL基本图元的绘制
- js实现整体,局部刷新
- 【数据库SQL实战】将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005
- Spring Boot 基础教程:集成 Knife4j
- 普通青年VS文艺青年VS2B青年,爆笑语录!
- 基于SpringBoot+MyBatis实现一套电商后台管理系统