《医用仪器软件系统开发-基于Qt(Windows版)》 课件 第5章 Qt程序设计_第1页
《医用仪器软件系统开发-基于Qt(Windows版)》 课件 第5章 Qt程序设计_第2页
《医用仪器软件系统开发-基于Qt(Windows版)》 课件 第5章 Qt程序设计_第3页
《医用仪器软件系统开发-基于Qt(Windows版)》 课件 第5章 Qt程序设计_第4页
《医用仪器软件系统开发-基于Qt(Windows版)》 课件 第5章 Qt程序设计_第5页
已阅读5页,还剩78页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

——基于Qt(Windows)版医用仪器软件设计MedicalInstrumentSoftwareDesign2022第5章Qt程序设计1-——BasedonQt(WindowsEdition)布局管理器关于这节课Aboutthiscourse.“在Qt程序设计的过程中,有4个非常重要的概念需要熟练掌握,分别为布局管理器,信号与槽,模态、半模态和非模态对话框,以及多线程,本章将详细介绍这4个概念。One

目录实验内容实验原理实验步骤本节任务实验内容在设计模式下设计界面时,从控件栏中移出的控件是可以随意摆放的,若使用手动对齐的方式,不仅费时费力,最终实现的效果也不理想。因此,对一个完善的应用程序而言,布局管理是必不可少的一部分。无论是想要界面中的控件有一个整齐的布局,还是想让界面能适应窗口的大小变化,都需要进行布局管理。Qt主要提供了QLayout类及其子类QVBoxLayout、QHBoxLayout、QGridLayout和QFormLayout等作为布局管理器,用来实现常用的布局管理功能,QLayout类及其子类的关系如下图所示。控件栏中布局管理组下的4个控件分别属于以上4个布局管理器。本节主要介绍这些布局管理器的用法。实验原理

垂直布局管理器QVBoxLayout可以使子控件在垂直方向上排成一列,如右图所示。进行界面设计的方式有两种:①打开ui文件后,在设计模式下直接将控件栏中的控件移入界面中进行摆放,并在属性设置框中设置属性;②通过编写代码的方式创建界面,并完成向界面中添加控件和设置控件属性等步骤。两种方法各有优劣,因此,可以采用二者相结合的方式来完成界面设计。使用方法①实现右图的界面比较简单直观,只需从控件栏中将VerticalLayout控件移入界面,然后再将3个PushButton控件移入VerticalLayout控件中,最后依次修改PushButton按钮的文本即可。1.QVBoxLayout这里主要介绍方法②,代码如下:还有一些常用的方法如下:2.QHBoxLayout水平布局管理器QHBoxLayout可以使子控件在水平方向上排成一行,其用法与QVBoxLayout基本一致,代码如下,效果如右凸所示:3.QgridLayout网格布局管理器QGridLayout可以使子控件按网格的形式来布局,管理器中的控件被划分为行和列,行和列的交叉形成一个个单元格,控件即可放入这些单元格中。通常将控件放进网格布局管理器的一个单元格中即可,但有些控件也可能需要占用多个单元格,这时就需要用到addWidget()方法的一个重载版本,原型如下:voidQGridLayout::addWidget(QWidget*widget,intfromRow,intfromColumn,introwSpan,intcolumnSpan,Qt::Alignmentalignment=Qt::Alignment())。row和column分别为控件开始的行数和列数,rowSpan和columnSpan分别是控件占用的行数和列数。用法示例如下:4.QFormLayout表单布局管理器QFormLayout用来管理表单的输入控件和与之相关的标签。表单布局管理器将子控件分为两列,左边一列通常为标签,右边一列通常为一些输入部件,如行编辑框LineEdit和数字显示框SpinBox等。可以通过addRow()方法来添加表单项,即创建一个带有指定文本的QLabel和QWidget控件行,该方法原型为voidQFormLayout::addRow(constQString&labelText,QWidget*field)具体用法和效果如下:5.布局管理器嵌套使用在进行一些复杂的界面设计时,仅使用一种布局管理器往往会使界面过于单调,且有些布局需要较大的代码量才能实现。这时就需要灵活使用多种布局管理器,多种布局管理器之间除了可以独立使用,还可以嵌套使用。实验步骤新建项目完善项目构建并运行项目本节任务在设计模式下,直接放置布局管理器并摆放其他控件,或使用代码编写和手动布局结合的方式,再次实现本节实验的布局。对比总结这些布局方式各有哪些优势。——基于Qt(Windows)版医用仪器软件设计MedicalInstrumentSoftwareDesign2022第5章Qt程序设计2-——BasedonQt(WindowsEdition)信号与槽关于这节课Aboutthiscourse.“One

在Qt程序设计的过程中,有4个非常重要的概念需要熟练掌握,分别为布局管理器,信号与槽,模态、半模态和非模态对话框,以及多线程,本章将详细介绍这4个概念。目录实验内容实验原理实验步骤本节任务实验内容信号与槽(signal&slot)是Qt编程的基础,也是Qt不同于其他开发框架的核心特征。信号与槽用于完成界面操作的响应,是实现任意两个对象之间通信的机制。本节先介绍信号与槽的特点和用法,然后通过一个简单的实验来介绍实际应用。实验原理

Qt的窗口部件在用户操作或内部状态发生变化时,会发出特定的信号来通知关注这个信号的对象。槽就是用于响应信号的函数,可以通过关键字public/protected/privateslots在类中进行声明。槽函数与一般函数不同的是:槽函数可以与信号关联,当信号发出时,与之关联的槽函数将会自动执行。与槽函数关联的信号除了可以是操作窗口部件自动发出的信号,还可以是用户自定义的信号,这些信号在类中用关键字signals声明,且无需定义,返回值为void类型。槽函数可以有参数,但参数类型必须与信号的参数类型相对应,参数个数不能多于信号的参数个数(参数个数少于信号的参数个数时,缺少的只能是最后一个或几个参数)。若要将一个窗口部件的变化情况通知给另一个窗口部件,则一个窗口部件发出信号,另一个窗口部件的槽接收此信号并进行相应的操作,这样即可实现两个窗口部件之间的通信。每个Qt对象都包含若干个未定义的信号与槽,当某个特定事件发生时,会发射一个信号,与该信号关联的槽函数则会响应信号并完成相应处理。例如,按钮PushButton最常见的信号就是单击时发出的clicked()信号;组合框ComboBox最常见的信号是列表项中发生改变时发出的CurrentIndexChanged()信号,合理地利用这些信号可以使程序的逻辑设计变得更简便。1.信号与槽简介2.信号与槽的用法信号与槽的关联是通过QObject::connect()方法来实现的,connect()是QObject类的一个方法,QObject类是所有Qt类的基类,在实际调用时可以省略前面的限定符。具体格式如下:connect(Object1,SIGNAL(signal()),Object2,SLOT(slot()));Object1为发出信号的对象Object2为接收信号的对象signal()为待发送的信号slot()是信号接收对象的槽函数3.信号与槽的连接方式信号与槽并非只能是一一对应的关系,一个信号可以关联到多个槽,多个信号也可以关联到同一个槽,甚至一个信号还能关联到另一个信号,如下图所示:(1)一个信号关联多个槽:

当一个信号关联多个槽时,若该信号触发,槽函数将按照关联的顺序依次执行。在上述代码中表现为:对象Object2发出信号signal2()时,对象Object1依次执行槽函数slot1()和slot2()。(2)多个信号关联同一个槽:

当多个信号关联同一个槽时,其中任何一个信号触发都将执行槽函数。在上述代码中表现为:无论对象Object3发出信号signal1()还是signal2(),对象Object2都会执行槽函数slot2()。(3)一个信号关联另一个信号:

当一个信号关联另一个信号时,前者的发出将触发后者发出。在上述代码中表现为:对象Object1发出信号signal1()时,对象Object2也将发出信号signal1()。信号与槽除了可以使用connect()方法进行手动关联,还可以用自动关联的方式实现:双击ui文件进入设计模式,从左侧控件栏中将控件移入界面后,右键单击控件,在弹出的菜单项中选择“转到槽”,选择一个信号并单击OK按钮。此时,在.h和.cpp文件中会分别自动添加槽函数的声明和实现,槽函数名的格式为:on_xxx_xxx(),含义为:on_控件名称_信号类型(),如on_button_clicked()。4.信号与槽的特点(1)类型安全信号与槽在参数类型上一一对应,且槽的参数个数不能多于信号的参数个数(槽的参数个数少于信号的参数个数时,缺少的只能是最后一个或几个参数)。若在编写代码时出现信号与槽参数类型不对应或信号的参数个数少于槽等错误,编译器就会报错。(2)松散耦合信号与槽机制减弱了Qt对象的耦合度。发出信号的对象只需在适当的时机将信号发出即可,无需知道此信号将被哪些槽接收,是否已被接收。同样的,槽也不需要知道哪些信号关联了自己,只需在收到信号后执行槽函数即可。(3)灵活简便信号与槽机制使界面中各个组件的交互操作变得十分灵活简便。虽然与回调函数相比,信号与槽机制的运行速度偏慢,但对于实时程序来说,相较于信号与槽机制带来的灵活性和简便性,这一点点性能损耗是可以忽略的。实验步骤新建项目添加C++Class完善namemodify.h完善namemodify.cpp完善widget.h完善widget.cpp构建并运行项目本节任务本实验实现了一个信号关联一个槽和关联多个槽,尝试实现一个信号关联另一个信号以及多个信号关联同一个槽。——基于Qt(Windows)版医用仪器软件设计MedicalInstrumentSoftwareDesign2022第5章Qt程序设计2-——BasedonQt(WindowsEdition)信号与槽关于这节课Aboutthiscourse.“One

在Qt程序设计的过程中,有4个非常重要的概念需要熟练掌握,分别为布局管理器,信号与槽,模态、半模态和非模态对话框,以及多线程,本章将详细介绍这4个概念。目录实验内容实验原理实验步骤本节任务实验内容

信号与槽(signal&slot)是Qt编程的基础,也是Qt不同于其他开发框架的核心特征。信号与槽用于完成界面操作的响应,是实现任意两个对象之间通信的机制。本节先介绍信号与槽的特点和用法,然后通过一个简单的实验来介绍实际应用。实验原理

Qt的窗口部件在用户操作或内部状态发生变化时,会发出特定的信号来通知关注这个信号的对象。槽就是用于响应信号的函数,可以通过关键字public/protected/privateslots在类中进行声明。槽函数与一般函数不同的是:槽函数可以与信号关联,当信号发出时,与之关联的槽函数将会自动执行。

与槽函数关联的信号除了可以是操作窗口部件自动发出的信号,还可以是用户自定义的信号,这些信号在类中用关键字signals声明,且无需定义,返回值为void类型。槽函数可以有参数,但参数类型必须与信号的参数类型相对应,参数个数不能多于信号的参数个数(参数个数少于信号的参数个数时,缺少的只能是最后一个或几个参数)。

若要将一个窗口部件的变化情况通知给另一个窗口部件,则一个窗口部件发出信号,另一个窗口部件的槽接收此信号并进行相应的操作,这样即可实现两个窗口部件之间的通信。每个Qt对象都包含若干个未定义的信号与槽,当某个特定事件发生时,会发射一个信号,与该信号关联的槽函数则会响应信号并完成相应处理。例如,按钮PushButton最常见的信号就是单击时发出的clicked()信号;组合框ComboBox最常见的信号是列表项中发生改变时发出的CurrentIndexChanged()信号,合理地利用这些信号可以使程序的逻辑设计变得更简便。1.信号与槽简介2.信号与槽的用法

信号与槽的关联是通过QObject::connect()方法来实现的,connect()是QObject类的一个方法,QObject类是所有Qt类的基类,在实际调用时可以省略前面的限定符。具体格式如下:connect(Object1,SIGNAL(signal()),Object2,SLOT(slot()));Object1为发出信号的对象Object2为接收信号的对象signal()为待发送的信号slot()是信号接收对象的槽函数3.信号与槽的连接方式

信号与槽并非只能是一一对应的关系,一个信号可以关联到多个槽,多个信号也可以关联到同一个槽,甚至一个信号还能关联到另一个信号,如下图所示:(1)一个信号关联多个槽:

当一个信号关联多个槽时,若该信号触发,槽函数将按照关联的顺序依次执行。在上述代码中表现为:对象Object2发出信号signal2()时,对象Object1依次执行槽函数slot1()和slot2()。(2)多个信号关联同一个槽:

当多个信号关联同一个槽时,其中任何一个信号触发都将执行槽函数。在上述代码中表现为:无论对象Object3发出信号signal1()还是signal2(),对象Object2都会执行槽函数slot2()。(3)一个信号关联另一个信号:

当一个信号关联另一个信号时,前者的发出将触发后者发出。在上述代码中表现为:对象Object1发出信号signal1()时,对象Object2也将发出信号signal1()。

信号与槽除了可以使用connect()方法进行手动关联,还可以用自动关联的方式实现:双击ui文件进入设计模式,从左侧控件栏中将控件移入界面后,右键单击控件,在弹出的菜单项中选择“转到槽”,选择一个信号并单击OK按钮。此时,在.h和.cpp文件中会分别自动添加槽函数的声明和实现,槽函数名的格式为:on_xxx_xxx(),含义为:on_控件名称_信号类型(),如on_button_clicked()。4.信号与槽的特点(1)类型安全信号与槽在参数类型上一一对应,且槽的参数个数不能多于信号的参数个数(槽的参数个数少于信号的参数个数时,缺少的只能是最后一个或几个参数)。若在编写代码时出现信号与槽参数类型不对应或信号的参数个数少于槽等错误,编译器就会报错。(2)松散耦合信号与槽机制减弱了Qt对象的耦合度。发出信号的对象只需在适当的时机将信号发出即可,无需知道此信号将被哪些槽接收,是否已被接收。同样的,槽也不需要知道哪些信号关联了自己,只需在收到信号后执行槽函数即可。(3)灵活简便信号与槽机制使界面中各个组件的交互操作变得十分灵活简便。虽然与回调函数相比,信号与槽机制的运行速度偏慢,但对于实时程序来说,相较于信号与槽机制带来的灵活性和简便性,这一点点性能损耗是可以忽略的。实验步骤新建项目添加C++Class完善namemodify.h完善namemodify.cpp完善widget.h完善widget.cpp构建并运行项目本节任务

本实验实现了一个信号关联一个槽和关联多个槽,尝试实现一个信号关联另一个信号以及多个信号关联同一个槽。——基于Qt(Windows)版医用仪器软件设计MedicalInstrumentSoftwareDesign2022第5章Qt程序设计3-——BasedonQt(WindowsEdition)模态、非模态和半模态对话框关于这节课Aboutthiscourse.“One

在Qt程序设计的过程中,有4个非常重要的概念需要熟练掌握,分别为布局管理器,信号与槽,模态、半模态和非模态对话框,以及多线程,本章将详细介绍这4个概念。目录实验内容实验原理实验步骤本节任务实验内容模态、非模态和半模态对话框是应用程序设计时经常需要用到的设计思想。本节先介绍模态、非模态和半模态对话框的基本概念,然后通过一个简单的实验来介绍三种对话框的具体用法和区别。实验原理

模态对话框是指阻塞同一应用程序中其他可视窗口输入的对话框。模态对话框有自己的事件循环,用户必须先完成这个对话框中的交互操作并且关闭后,才能访问应用程序中的其他窗口。例子:如下图,需要点击“确定”或“取消”后,才可以操作当前应用的其他窗口。1.模态对话框模态对话框仅阻止访问与自身相关联的窗口,允许用户继续使用其他应用程序中的窗口,常见于新建项目和应用程序的配置选项的界面。显示模态对话框最常用的方法是调用exec()方法,该方法调用显示一个模态对话框后,代码不能向下运行,直到该方法返回。当对话框关闭时,exec()将提供一个返回值,程序继续从调用exec()的地方运行。要使对话框关闭时返回相应的值,通常将按钮连接到默认的槽函数。例如:将“确定”按钮连接到accept()槽,“取消”按钮连接到reject()槽。这样,当单击“确定”按钮时exec()方法返回Accepted,单击“取消”按钮时exec()方法返回。2.非模态对话框与模态对话框相反,非模态对话框是独立于应用程序中其他窗口的对话框,不会阻塞用户对其他窗口的交互操作,同时,用户还可以与对话框自身进行交互。直接使用show()方法即可显示非模态对话框。与exec()方法不同,当调用show()方法后,代码不会被阻塞,可以继续往下执行,且控制权会立即返还给调用者。非模态对话框常见于文字处理中的“查找”和“替换”场景。3.半模态对话框

半模态对话框介于模态和非模态之间。半模态对话框会阻塞其他窗口的响应,不能进行单击、输入和拖动等任何操作,但是代码不会被阻塞,可以继续往下运行。半模态对话框需要通过setModal(true)和show()方法来实现。setModal(true)指定窗口为模态窗口,也可以使用setWindowModality()方法来代替。调用show()方法显示对话框,代码继续运行。实验步骤新建项目添加对话框窗体文件和类完善dialog.h文件完善dialog.cpp文件完善widget.h完善widget.cpp构建并运行项目本节任务从模态对话框的测试结果来看,并不能体现出其阻止代码继续向下运行的特点,试修改modalButtonClicked()槽函数,体现这一特点。——基于Qt(Windows)版医用仪器软件设计MedicalInstrumentSoftwareDesign2022第5章Qt程序设计3-——BasedonQt(WindowsEdition)模态、非模态和半模态对话框关于这节课Aboutthiscourse.“One

在Qt程序设计的过程中,有4个非常重要的概念需要熟练掌握,分别为布局管理器,信号与槽,模态、半模态和非模态对话框,以及多线程,本章将详细介绍这4个概念。目录实验内容实验原理实验步骤本节任务实验内容

模态、非模态和半模态对话框是应用程序设计时经常需要用到的设计思想。本节先介绍模态、非模态和半模态对话框的基本概念,然后通过一个简单的实验来介绍三种对话框的具体用法和区别。实验原理

模态对话框是指阻塞同一应用程序中其他可视窗口输入的对话框。模态对话框有自己的事件循环,用户必须先完成这个对话框中的交互操作并且关闭后,才能访问应用程序中的其他窗口。例子:如下图,需要点击“确定”或“取消”后,才可以操作当前应用的其他窗口。1.模态对话框

模态对话框仅阻止访问与自身相关联的窗口,允许用户继续使用其他应用程序中的窗口,常见于新建项目和应用程序的配置选项的界面。

显示模态对话框最常用的方法是调用exec()方法,该方法调用显示一个模态对话框后,代码不能向下运行,直到该方法返回。当对话框关闭时,exec()将提供一个返回值,程序继续从调用exec()的地方运行。要使对话框关闭时返回相应的值,通常将按钮连接到默认的槽函数。

例如:将“确定”按钮连接到accept()槽,“取消”按钮连接到reject()槽。这样,当单击“确定”按钮时exec()方法返回Accepted,单击“取消”按钮时exec()方法返回。2.非模态对话框

与模态对话框相反,非模态对话框是独立于应用程序中其他窗口的对话框,不会阻塞用户对其他窗口的交互操作,同时,用户还可以与对话框自身进行交互。

直接使用show()方法即可显示非模态对话框。与exec()方法不同,当调用show()方法后,代码不会被阻塞,可以继续往下执行,且控制权会立即返还给调用者。

非模态对话框常见于文字处理中的“查找”和“替换”场景。3.半模态对话框

半模态对话框介于模态和非模态之间。半模态对话框会阻塞其他窗口的响应,不能进行单击、输入和拖动等任何操作,但是代码不会被阻塞,可以继续往下运行。

半模态对话框需要通过setModal(true)和show()方法来实现。setModal(true)指定窗口为模态窗口,也可以使用setWindowModality()方法来代替。调用show()方法显示对话框,代码继续运行。实验步骤新建项目添加对话框窗体文件和类完善dialog.h文件完善dialog.cpp文件完善widget.h完善widget.cpp构建并运行项目本节任务

从模态对话框的测试结果来看,并不能体现出其阻止代码继续向下运行的特点,试修改modalButtonClicked()槽函数,体现这一特点。——基于Qt(Windows)版医用仪器软件设计MedicalInstrumentSoftwareDesign2022第5章Qt程序设计3-——BasedonQt(WindowsEdition)多线程关于这节课Aboutthiscourse.“One

在Qt程序设计的过程中,有4个非常重要的概念需要熟练掌握,分别为布局管理器,信号与槽,模态、半模态和非模态对话框,以及多线程,本章将详细介绍这4个概念。目录实验内容实验原理实验步骤本节任务实验内容为了满足用户构造复杂图形界面系统的需求,Qt提供了丰富的多线程编程支持。本节将介绍多线程的优点和创建方法,然后介绍线程同步的概念,最后通过实验设计一个多线程的程序。实验原理一个应用程序通常只有一个线程,称为主线程。线程内的操作是按顺序执行的,如果在主线程中执行一些耗时的操作(如加载图片、大型文件读取、文件传输和密集计算等),就会阻塞主线程,从而导致用户界面失去响应。在这种情况下,单一线程就无法适应应用程序的需求。可以再创建一个单独的线程,将耗时的操作转移到新建的线程中执行,并处理好该线程与主线程之间的同步与数据交互即可避免上述问题,这就是多线程应用程序。1.什么是多线程线程A线程B任务1任务2任务3任务4任务52.多线程的特点相比于单线程,多线程具有以下特点。(1)可提高应用程序的响应速度。在多线程下,可将一些耗时的操作置于一个单独的线程,使用户界面一直处于活动状态,避免因主线程阻塞而失去响应。(2)可提高多处理器系统的CPU利用率。当线程数小于CPU数目时,操作系统会合理分配各个线程使其分别在不同的CPU上运行。(3)改善程序结构。可将一些代码量庞大的复杂线程分为多个独立或半独立的执行部分,既可以增加代码的可读性,也有利于代码的维护。(4)可以分别设置各个任务的优先级以优化性能。(5)等候使用共享资源时会造成程序的运行速度变慢。这些共享资源主要是独占性的资源,如打印机等。(6)管理多个线程需要额外的CPU开销。多线程的使用会给系统带来上下文切换的额外负担(上下文切换是指内核在CPU上对进程或线程进行切换)。(7)容易造成线程的死锁。(8)同时读写公有变量容易造成脏读(读出无效数据)。3.如何使用多线程

Qt提供了对多线程操作的支持,包括一套独立于平台的线程类库、一个线程安全的事件发送途径,及可跨线程使用的信号与槽。此外,还提供了用于线程之间通信与同步的若干机制,使得基于Qt的多线程应用程序开发变得灵活简单。

Qt中的QThread类提供了管理线程的方法,是实现多线程的核心类。一个QThread类的对象管理一个线程,该线程可以与应用程序中的其他线程分享数据,但是是独立运行的。创建一个新线程的方法为:自定义一个继承自QThread的类,并重写run()方法,在run()方法中添加该线程需要完成的任务,然后在主线程中创建一个上述自定义类的对象并实例化,最后调用QThread::start()方法开始新线程。相比于一般的程序都是从main()函数开始执行的,QThread是从run()方法开始执行的,start()方法默认调用run()方法。QThread会在线程启动、结束和终止时分别发出started()、finished()和terminated()信号。可以用isRunning()和isFinished()来查询线程的状态,还可以使用wait()来阻塞线程,直到线程结束。run()通过调用exec()方法来开启事件循环,并在线程内运行一个Qt事件循环,可以使用quit()退出事件循环。当从run()方法返回后,线程便执行结束。应用程序主程序fun1()fun2()…子程序继承QThreadrun()4.线程同步线程同步主要是为了协调各个线程之间的工作,以便更好地完成一些任务。虽然多线程的思想是多个线程尽可能多地并发执行,但有时候有些线程需要暂停等待其他线程,如两个线程同时访问同一个全局变量,如果没有线程同步,读出的结果通常是不确定的。

Qt中提供了丰富的类用于进行线程同步,常用的有QMutex、QReadWriteLock、QSemaphore和QWaitCondition。(1)QMutexQMutex是基于互斥量的线程同步类,可以确保多个线程对同一资源的顺序访问。使用QMutex定义一个互斥量mutex,通过mutex.lock()和mutex.unlock()分别锁定和解锁互斥量,则处于mutex.lock()和mutex.unlock()之间的代码为保护状态,同一时间最多只能有一个线程访问此段代码。当一个线程锁定互斥量后,若另一个线程也尝试调用lock()来锁定这个互斥量,则不但无法成功锁定,反而会阻塞执行直到前一个线程解锁互斥量。通过调用tryLock()方法也可以锁定互斥量,但与lock()不同的是,如果成功锁定就返回true;如果其他线程已经锁定这个互斥量则返回false,但不会阻塞线程执行。(1)QMutexQMutex是基于互斥量的线程同步类,可以确保多个线程对同一资源的顺序访问。使用QMutex定义一个互斥量mutex,通过mutex.lock()和mutex.unlock()分别锁定和解锁互斥量,则处于mutex.lock()和mutex.unlock()之间的代码为保护状态,同一时间最多只能有一个线程访问此段代码。当一个线程锁定互斥量后,若另一个线程也尝试调用lock()来锁定这个互斥量,则不但无法成功锁定,反而会阻塞执行直到前一个线程解锁互斥量。通过调用tryLock()方法也可以锁定互斥量,但与lock()不同的是,如果成功锁定就返回true;如果其他线程已经锁定这个互斥量则返回false,但不会阻塞线程执行。例:同时在两个线程分别调用方法1,方法2方法1方法2输出结果:ABCABCDEFDEF输出结果:ABCDEFABCDEF(2)QReadWriteRead

使用互斥量在提升线程安全性的同时也有弊端:若程序中有多个线程仅需读取某一公有变量,如果使用互斥量则必须排队访问,这样就会降低程序的性能,使用QReadWriteRead类可以避免上述问题。QReadWriteRead以读锁定或写锁定的方式保护一段代码,允许多个线程以只读的形式访问公有资源。常用方法有lockForRead()、lockForWrite()、unlock()、tryLockForRead()和tryLockForWrite()。例:右图为Qt读写锁的演示及验证,在下图中可以看出两个读取数据的函数会一起调用(代表读写锁支持读取锁线程一起运行),且数据操函数并不会调用;而当数据操作函数调用时,两个数据读取函数也不会调用。由此可知,当读取锁开启时,写入锁不能进入,反之亦然。(3)QSemaphoreQSemaphore为基于信号量的线程同步类,即对互斥量功能的扩展。使用互斥量只能保护一个资源,信号量可以保护多个资源。QSemaphore的构造方法可以指定一个参数,即为当前可用资源的个数,默认为0。QSemaphore提供了acquire()和release()方法来获取和释放资源。(4)QWaitConditionQWaitCondition允许一个线程在满足特定条件后,通知或唤醒其他多个线程。唤醒方式是通过wakeOne()和wakeAll()方法,前者唤醒一个处于等待状态的线程,后者唤醒所有处于等待状态的线程。实验步骤新建项目添加对话框窗体文件和类完善dialog.h文件完善dialog.cpp文件完善widget.h完善widget.cpp构建并运行项目本节任务从模态对话框的测试结果来看,并不能体现出其阻止代码继续向下运行的特点,试修改modalButtonClicked()槽函数,体现这一特点。——基于Qt(Windows)版医用仪器软件设计MedicalInstrumentSoftwareDesign2022第5章Qt程序设计3-——BasedonQt(WindowsEdition)多线程关于这节课Aboutthiscourse.“One

在Qt程序设计的过程中,有4个非常重要的概念需要熟练掌握,分别为布局管理器,信号与槽,模态、半模态和非模态对话框,以及多线程,本章将详细介绍这4个概念。目录实验内容实验原理实验步骤本节任务实验内容

为了满足用户构造复杂图形界面系统的需求,Qt提供了丰富的多线程编程支持。本节将介绍多线程的优点和创建方法,然后介绍线程同步的概念,最后通过实验设计一个多线程的程序。实验原理

一个应用程序通常只有一个线程,称为主线程。线程内的操作是按顺序执行的,如果在主线程中执行一些耗时的操作(如加载图片、大型文件读取、文件传输和密集计算等),就会阻塞主线程,从而导致用户界面失去响应。在这种情况下,单一线程就无法适应应用程序的需求。可以再创建一个单独的线程,将耗时的操作转移到新建的线程中执行,并处理好该线程与主线程之间的同步与数据交互即可避免上述问题,这就是多线程应用程序。1.什么是多线程线程A线程B任务1任务2任务3任务4任务52.多线程的特点相比于单线程,多线程具有以下特点。(1)可提高应用程序的响应速度。在多线程下,可将一些耗时的操作置于一个单独的线程,使用户界面一直处于活动状态,避免因主线程阻塞而失去响应。(2)可提高多处理器系统的CPU利用率。当线程数小于CPU数目时,操作系统会合理分配各个线程使其分别在不同的CPU上运行。(3)改善程序结构。可将一些代码量庞大的复杂线程分为多个独立或半独立的执行部分,既可以增加代码的可读性,也有利于代码的维护。(4)可以分别设置各个任务的优先级以优化性能。(5)等候使用共享资源时会造成程序的运行速度变慢。这些共享资源主要是独占性的资源,如打印机等。(6)管理多个线程需要额外的CPU开销。多线程的使用会给系统带来上下文切换的额外负担(上下文切换是指内核在CPU上对进程或线程进行切换)。(7)容易造成线程的死锁。(8)同时读写公有变量容易造成脏读(读出无效数据)。3.如何使用多线程

Qt提供了对多线程操作的支持,包括一套独立于平台的线程类库、一个线程安全的事件发送途径,及可跨线程使用的信号与槽。此外,还提供了用于线程之间通信与同步的若干机制,使得基于Qt的多线程应用程序开发变得灵活简单。

Qt中的QThread类提供了管理线程的方法,是实现多线程的核心类。一个QThread类的对象管理一个线程,该线程可以与应用程序中的其他线程分享数据,但是是独立运行的。

创建一个新线程的方法为:自定义一个继承自QThread的类,并重写run()方法,在run()方法中添加该线程需要完成的任务,然后在主线程中创建一个上述自定义类的对象并实例化,最后调用QThread::start()方法开始新线程。

相比于一般的程序都是从main()函数开始执行的,QThread是从run()方法开始执行的,start()方法默认调用run()方法。QThread会在线程启动、结束和终止时分别发出started()、finished()和terminated()信号。可以用isRunning()和isFinished()来查询线程的状态,还可以使用wait()来阻塞线程,直到线程结束。run()通过调用exec()方法来开启事件循环,并在线程内运行一个Qt事件循环,可以使用quit()退出事件循环。当从run()方法返回后,线程便执行结束。应用程序主程序fun1()fun2()…子程序继承QThreadrun()4.线程同步

线程同步主要是为了协调各个线程之间的工作,以便更好地完成一些任务。虽然多线程的思想是多个线程尽可能多地并发执行,但有时候有些线程需要暂停等待其他线程,如两个线程同时访问同一个全局变量,如果没有线程同步,读出的结果通常是不确定的。

Qt中提供了丰富的类用于进行线程同步,常用的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论