需求的提出
窗口本身就是一个死循环,在这样一个死循环中执行任何耗时的操作,都会导致程序崩溃。所以多线程对于窗口编程而言是必要的。
例如,在窗口中拖入一个 pushButton 和 lineEdit ,将 pushButton 的名字改为 pbStart ,然后为其绑定一个函数,函数中创建一个死循环,并让死循环中的内容实时输出到 lineEdit 。
(相关资料图)
接下来设计一个逻辑,当点击 pbStart 之后,开始执行死循环,同时按钮内容变为 Stop ;当按钮内容为 Stop 时,点击按钮,停止执行死循环。
所以,需要设计一个用于控制循环是否继续执行的成员变量,在 MainWindow 的头文件中添加私有成员 bool flag 。在 cpp 文件中添加 flag = true 。
然后转到设计界面 ,右键 pbStart 按钮->转到槽 ->clicked() 。从而 MainWindow 中添加了一个名为 on_pbStart_clicked 的函数,填充其内容为
void MainWindow::on_pbStart_clicked(){ int i= 0; bool flag = QString::compare(ui->pbStart->text(),\"start\"); if(flag) ui->pbStart->setText(\"stop\"); while(flag){ i++; ui->lineEdit->setText(QString::number(i)); }}
复制
Jetbrains全家桶1年46,售后保障稳定
结果运行之后,果然陷入了死循环,程序也无法响应了,最过分的是 lineEdit 并没有变化,这个时候就要考虑多线程。
多线程
QThread 是Qt中最基础的线程类,每个实例都可以控制一个线程。其传统的调用方式是,新建一个继承 QThread 的类,然后将耗时任务写入 run 函数。而自QT4.4之后,则建议通过 moveToThread() 函数来调用多线程。
首先新建一个类,在项目中 Ctrl + N ,在弹出对话框中选择 Files and Classes ->C/C++ ->C++ Class ,定义类的名称为 ThTest ,并选中 QObject 。
令该类继承 QObject ,将头文件中的 ThTest 改为
class ThTest : public QObject{ Q_OBJECTpublic: ThTest(); ~ThTest(); void Func(void);};
复制
相应地, cpp 文件的内容为
#include \"thtest.h\"#include #include ThTest::ThTest(){ }ThTest::~ThTest(){ }void ThTest::Func(){ int NowNum = 0; while(true){ NowNum++; qDebug()<
复制
然后更改 mainwindow 的代码,在其头文件内容如下
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include #include #include #include #include \"thtest.h\"QT_BEGIN_NAMESPACEnamespace Ui { class MainWindow; }QT_END_NAMESPACEclass MainWindow : public QMainWindow{ Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();signals:void ToThread(); // 信号private slots:void on_pbStart_clicked();private:Ui::MainWindow *ui;QThread *qThTest;ThTest *th1;};#endif
复制
然后将 cpp 文件中的 on_pbStart_clicked 函数改为
void MainWindow::on_pbStart_clicked(){ qThTest = new QThread;th1 = new ThTest;connect(this,&MainWindow::ToThread,th1,&ThTest::Func);th1->moveToThread(qThTest);qThTest->start();emit ToThread();}
复制
其中, connect 将 ToThread 函数和 ThTest 中的 Func 函数绑定在了一起。也就是说,当这边发射 ToThread 的信号的时候, Th1 会执行 Func 这个函数。
所以,当线程启动后,通过 emit 发射 ToThread 信号,果然命令行中会持续输出数字了,同时窗口并不会死掉。
到了这一步,其实已经可以处理一些多线程任务了,但还不能把递增的 NowNum 显示到主窗口上,从而让 lineEdit 看上去有些鸡肋。为了实现在窗口上显示递增的数字,接下来需要做的就是线程间的通信。
线程间通信
得益于Qt的信号槽机制,多线程之间的通信并不复杂。乃至于,可以广义地认为 emit ToThread() 本身也是一个线程间通信的过程。
所以只需在 on_pbStart_clicked 中添加一条
connect(th1,SIGNAL(sendInt(int)),this,SLOT(getInt(int)));
复制
意思就是 th1 发射一个 sendInt(int) , this 接收一个 getInt(int) ,这两个函数的名字无所谓,但一定不包含形参,而只有形参的数据类型。
接下来,在 thtest.h 中添加 sendInt ,
signals:void sendInt(int);
复制
并更改其 Func 函数
void ThTest::Func(){ int NowNum = 0;while(true){ QThread::sleep(1);emit sendInt(NowNum++);}}
复制
最后,在 mainwindow.h 中添加
private slots:void getInt(int);
复制
以及 cpp 文件中的
void MainWindow::getInt(int num){ ui->lineEdit->setText(QString::number(num));}
复制
这样,在点击 start 之后,就可以看到 lineEdit 上数字的变化了。
终止多线程
最后,回到一开始的需求,是点击 start 开始,然后按钮变为 stop ,点击 stop 后再停止。
考虑到 terminate 并不安全,故而采用终结 while 的方式来退出死循环。方法是在 ThTest 中添加一个 bool 类型的成员 running ,即在头文件中添加
public:bool running=true;
复制
并更改源文件中的 while 循环
void ThTest::Func(){ int NowNum = 0;while(running){ emit sendInt(NowNum++);QThread::sleep(1);}}
复制
最后修改 on_pbStart_clicked
void MainWindow::on_pbStart_clicked(){ bool flag = QString::compare(ui->pbStart->text(),\"stop\");qDebug()<pbStart->text();th1->running = flag;ui->pbStart->setText(flag?\"stop\":\"start\");if(flag){ th1->moveToThread(qThTest);qThTest->start();emit ToThread();}elseui->lineEdit->setText(\"0\");}
复制
并把 th1 等初始化过程移除去
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this);qThTest = new QThread;th1 = new ThTest;connect(th1,SIGNAL(sendInt(int)),this,SLOT(getInt(int)));connect(this,&MainWindow::ToThread,th1,&ThTest::Func);}
复制
结果线程果然终止了
【领 QT开发教程 学习资料, 点击下方链接莬费领取↓↓ ,先码住不迷路~】
点击这里:
发布者:全栈程序员栈长
出处:https://javaforall.cn/234553.html原文链接:https://javaforall.cn
下一篇:最后一页
X 关闭
-
QT多线程实战_Qt多线程开发项目 天天关注
需求的提出窗口本身就是一个死循环,在这样一个死循环中执行任何耗时的操作,都会导致程序崩溃。所以多线程
-
自贡高新区:青少年绿色储能科普工作室揭牌 全球报道
5月30日,自贡高新区红旗街道华景社区与兴储世纪科技股份有限公司签署共驻共建协议,并举行了青少年绿色储
-
普通护照可以去港澳吗(普通护照可以去哪些国家)
普通护照可以去港澳吗,普通护照可以去哪些国家这个很多人还不知道,现在让我们一起来看看吧!1、两个概念,
-
金田股份不超14.5亿可转债获上交所通过 东方投行建功 即时看
金田股份不超14 5亿可转债获上交所通过东方投行建功---中国经济网北京6月1日讯上海证券交易所上市审核委员
-
春蚕劫枉丝 第七集 聪慧善谋外柔内刚允/霸道强势染/虎视眈眈三/默默守护冲 焦点讯息
宴客厅,看到宸王离开,门被关上后,丁宏勋几人对视了一眼,将安之围了起来。刘奕宥轻佻的勾起安之的衣袖,
- 1吟安一个字捻断数根须翻译成中文_吟安一个字 天天新动态
- 2全球消息!张小泉(301055):6月1日技术指标出现看涨信号-“红三兵”
- 3每日视点!提前探访!将人行系统与“空中花园”融为一体,浮岛公园展露美丽容颜
- 4全年20场亲子活动等你来!这个“六一”他们在老弄堂一起过 热门看点
- 5杭州119.5亿元挂牌12宗宅地,计划于6月30日出让-世界速读
- 6新疆省造老银元价格(2023年06月01日)
- 7中国南玻集团冰麒麟玻璃首登央视总台 全球快资讯
- 8新时代 新征程 新伟业丨许昌加快企业绿色低碳转型推进制造业高质量发展 点“绿”成金 动能强劲|动态
- 9住民宿品毛茶!龙门南昆山着力打造一流生态旅游度假区-环球观热点
- 10彻底爆单!企业忙到“放弃订单”!江西:需求回暖 碳酸锂企业满负荷生产