LabVIEW事件结构的妙用
第9章_labview的高级应用(事件结构编程技巧)

通过“坐标”获取鼠标的位置,并把该坐标值赋给“鼠标 按下”的控件,从而达到控件被鼠标拖动的视觉效果。
在“鼠标释放”的分支中,通过“非法引用句柄常量”取 消对“鼠标移动”事件的注册,从而实现在鼠标释放后, 控件的位置不再跟随鼠标发生变化。
• 动态注册:动态事件注册与VI服务器相结合,
允许在程序运行时使用控件、VI或应用程序 的引用来动态地指定和改变产生事件。动态 注册在控制LabVIEW产生何种事件和何时产 生事件等方面更为灵活。
用布尔控件制作 的自定义控件
为这个自定义控 件动态注册了 “鼠标按下”事
件
1:放置“注册事件”函数 2:在“注册事件”函数输入端上连接一个引用 3:在“注册事件”函数事件源,选择该引用所对应的事件
第九章
Labview 的高级应用 ——事件结构之谜
用户界面
事
件
外部I/O
程序的其它部分
超时节点
事件结构
事件选择器
动态事件注册
事件数据节点程序代码Step2:处理事件分支程序
事件结构在循环体外, 因此不再执行
Step1:值第一次被改变 Step3:值再次被改变
事件结构编写黄金法则1
将事件结构放入While循环中!
生产者消费者 循环
事件结构
• 通知事件:
如“鼠标移动”、“键按下”等
• 过滤事件:
如“鼠标移动?”、“键按下?”等
数字”0-9” “-“ ”Backspace“
事件过滤节点
事件结构注册模式
• 静态注册:事件结构的每个分支具体处理哪 些事件,一旦VI开始运行,LabVIEW将自动 注册这些事件,并且在VI运行的整个过程中 无法改变事件结构所处理的事件。
LabVIEW虚拟仪器技术第4章-程序结构

基本程序结构
在各编程语言中,基本的程序结构有三种: 顺序结构、条件结构和循环结构。
LabVIEW中,除了具有上述三种程序结构外, 还提供了用于事件处理的事件结构。
此外,还有局部变量,属性节点和调用节点 等功能,为增加程序编写的灵活性提供了保障。
文本语言接口
在LabVIEW的图形化编程环境中,利用上述 程序结构可以解决很多非常复杂的问题。
范例
条件结构的输出隧道。
条件结构的输出方式
条件结构的输出有两种方式:
1.在条件分支内部输出数据
2.通过数据输出隧道,在条件结构外部输出数据
在分支内部输出数据更符合常规编程语言的编 程方式,但是从LabVIEW数据流的观点来看,并 不是最佳选择。
程序求输入数值的平方根,计算之前先判断 输入是否大于等于0。判断为真,结果由显示控件 输出,判断结果为假时,条件为真的分支不执行。
点击右键,在快捷菜单中我们可以添加或删 除每一帧。我们也可以通过拖曳的方式来改变每 一帧的大小。
顺序结构在执行时,会按照帧的顺序,从左 到右,依次执行每一帧。每一帧都有一个帧序号, 最小的帧序号为0,然后是1、2、3依次递增。
平铺式顺序结构因为代码是平铺的,因此代 码更直观,可读性较高。但是它的缺点是占用空 间较大。
针对于此,可以通过调用快捷菜单中的“替 换为层叠式顺序”功能,将平铺式的顺序结构转 换成层叠式的,以使VI看起来更为紧凑。
4.1.2 层叠式顺序结构
从本质上看,层叠式顺序结构和平铺式顺序 结构的功能完全相同,且二者可以相互转换。
层叠式顺序结构的创建
层叠式顺序结构外形类似于条件结构。它包 括一个或多个顺序执行的子程序框图或帧。
在很多情况下,程序员会需要多段代码按照预 先设定的顺序执行,这就需要顺序结构来帮忙了。
Labview 学习笔记

reference死锁问题LabVIEW中的引用经常需要和“In Place Element Structure”配合使用。
In Place Element Structure 对一个引用的数据进行处理时,为了保证多线程安全,它会锁住引用指向的数据;其它线程若需对同一数据做操作,必须能这个In Place Element Structure中所有代码执行完毕才可,这样就避免了多线程读写同一内存数据所产生的竞争问题。
举例来说,下面这段程序的执行时间是1秒:而下面这段程序的执行时间则是2秒:因为第二段程序中的两个In Place Element Structure必须顺序执行。
有了“锁住”这个操作,就有不小心造成死锁的可能。
比如对于同一数据的引用,千万不能嵌套使用In Place Element Structure,否则就会死锁:在上面这个示例中,程序运行至内层的In Place Element Structure,就会停在这里等外层In Place Element Structure运行结束,释放它锁住的数据;而对于外层In Place Element Structure来说,它内部的全部代码要运行结束,它才结束。
因而它们相互等待,造成了死锁。
Packed Project Libraries 2 –与Library的比较acked Project Library 从名字上来看,就是被包装好了的Project Library。
Project Library 是编程时候由程序员创建出来的。
比如下图这个工程,我在里面创建了一个叫做“My Algorithm Library.lvlib”的工程库。
它包含两个VI,其中一个是私有的。
Packed Project Library 并不是手工创建的,他是通过一个项目的生成规范,从Project Library 编译而来的。
比如上图的项目,我创建了一个Packed Library类型的生成规范。
Labview-学习笔记

Labview-学习笔记reference 死锁问题LabVIEW中的引用经常需要和“In Place Element Structure”配合使用。
In Place Element Structure 对一个引用的数据进行处理时,为了保证多线程安全,它会锁住引用指向的数据;其它线程若需对同一数据做操作,必须能这个In Place Element Structure中所有代码执行完毕才可,这样就避免了多线程读写同一内存数据所产生的竞争问题。
举例来说,下面这段程序的执行时间是1秒:而下面这段程序的执行时间则是2秒:因为第二段程序中的两个In Place Element Structure必须顺序执行。
有了“锁住”这个操作,就有不小心造成死锁的可能。
比如对于同一数据的引用,千万不能嵌套使用In Place Element Structure,否则就会死锁:Packed Project Library 并不是手工创建的,他是通过一个项目的生成规范,从Project Library 编译而来的。
比如上图的项目,我创建了一个Packed Library类型的生成规范。
我在这个生成规范中指定把“My Algorithm Library.lvlib”编译成Packed Project Library 。
编译的结果是在我指定的路径下生成了一个名为“My Algorithm Library.lvlibp”的文件。
它的后缀名仅比Packed Library多了一个字母p。
双击这个文件,可以打开它,看到他里面包含的VI:如果需要在其它项目中使用到这个Packed Project Library,我们可以直接把它加到另一个项目中去,下图是一个演示项目:Packed Project Library 看上去和Project Library 非常相似,用法也完全相同。
Packed Project Library 与Project Library•都是将功能相关的一组VI封装起来的方法;•库中的VI可以具有层次机构;•库中的VI都带有名字空间,名字空间是带有后缀名的库名;•都可以方便的放在项目管理器里使用尽管它们十分相似,Packed Project Library 与Project Library 相比,还是有一些明显区别的:•Packed Project Library 是通过编译生成的;•Packed Project Library 中的VI是编译后产生的,它们不能被修改;•Packed Project Library 包含有私有VI,但用户无法看到也不能使用它们;•Packed Project Library 把VI,.lvlib以及其它用到的文件都打成一个压缩包,用户在磁盘上就只能看到一个.lvlibp文件,看不到VI文件;•Packed Project Library 很适合作为最终产品发布给用户使用;•在项目中使用Packed Project Library 可以缩短编译时间,因为Packed Project Library 中的VI是已编译好的,不会再随项目编译一遍。
labview控制程序流程——labview事件结构

labview控制程序流程——labview事件结构1 事件结构及它的图形化表示法事件被用来通知用户有异步活动发生。
图形化语言的事件响应包括:用户界面事件、外部I/O 事件和程序其它部分的事件。
对事件的处理程序也被称为:事件驱动程序。
事件驱动程序可以分为若干个分支,每个分支处理不同的事件响应。
所以对事件的响应结果也可以控制程序的流程。
事件驱动机制来自于可视化的操系统,可视化操作系统对用户事件提供了简洁、有效的响应方式,最常见的事件来自于鼠标和键盘。
虚拟仪器借助于操作系统的事件处理机制实现了图形化语言的事件响应能力。
在没有引入事件结构之前,LabVIEW 是借助于轮询的方式来查询用户操作,由于轮询的方式会占用一定的CPU 资源,甚至可能遗漏事件,所以这种处理方式并非理想。
事件结构的出现避免了对CPU 资源的占用,同时也避免了事件的遗漏。
事件结构在函数选板》编程》结构子选板中可以找到,并可以将其直接拖拽到程序框图中,图形化表示的事件结构,参见下图。
图 1 图形化的事件结构与Case 结构和循环结构类似,事件结构也包含了一个主框架,这个框架内将用来放置事件处理的事件驱动程序代码。
如果事件处理任务众多,会有众多事件分支存在,在结构上类似Case 的多帧结构(选择器标签)。
当在程序框图上拖放一个事件结构时,我们只能看到上图所示的一帧已经预先注册的超时事件(Timeout),超时事件分支。
它具有定时延迟的基本功能(不包括While 循环),参见下图。
图 2 具有定时延迟的基本功能当然也可以采用另一种表示方法,参见下图。
图 3 利用事件结构内部节点获得中止时间通过这个例子也好理解内部节点中时间的含义(是事件响应的停止时间)。
超时事件超时事件是一种特殊的事件,当然也可以看成是默认的事件分支。
如果存在其它事件源时,超时事件完全可以被忽略或取消。
看下面一个例子。
图 4 仅有的两个事件之一超时事。
LabVIEW经典结构-组合动作执行模型

LabVIEW经典结构——组合动作执行模型
在LabVIEW应用程序开发中,广泛使用了一种高效的程序结构——组合动作执行模型。
该模型由While、Evnet(事件)、For、Case、enum(枚举)等向种结构和数据类型构成。
执行机理:面向对象的事件结构,响应前面板发生的针对控件的鼠标、键盘的动作,产生事件,并输出一个枚举数组,该数组作为For循环执行的索引,同时数组元素定义了执行的Case。
将各种事件响应进行分解为基本的动作单元,利用枚举数组定义出若干个由动作单元组合而成的动作序列,依据控件事件选择执行枚举数组,顺序完成对应的动作单元。
模型特点:重复利用各基本动作单元,增加代码复用率,程序更加简洁。
通过新建事件,可以定义任意组合的动作序列,灵活高效。
具有很强的模块化设计思想。
图1组合动作执行模型。
labview事件结构使用方法

labview事件结构使用方法在LabVIEW中,事件结构是一种可以按照事件的发生改变程序流程的数据结构,可以通过人机互动或者事件干预的方式产生事件驱动,在LabVIEW中是一种常用的数据结构,下面我就来讲解一下其具体的使用方法。
一、事件结构的使用目的在LabVIEW中一个重要的概念就是数据流,我们在编程的时候可以来设置某些事件来对数据流进行干预,比如说单击鼠标产生事件,按下键盘按键等,这些都可以被当作为事件结构的条件,进而实现对程序的控制。
二、事件结构的创建方法1.在程序窗口中的空白处单击鼠标右键,在弹出的函数选板中选择<结构>子选板,然后再选择<事件结构>并将其拖到程序框图中即可。
2.最基本的事件结构是由<程序框架>、<子框图标识符>和<事件数据节点>组成。
3.在刚创建事件结构时,会自动的创建一个<超时端口>,<超时端口>用于连接一个数值指定等待事件的毫秒数,如果超过设定的时间没有发生事件的话,程序就会产生一个超时事件。
4.<事件数据节点>用于访问事件的数据值,可以单击节点中的数据项,然后在弹出的菜单中,选择<选择项>,可以进行选择访问哪个事件数据的成员。
5.在事件结构的边框上单击鼠标右键,在弹出的菜单中选择<添加事件分支>,即可完成子框图的添加。
三、对事件进行编辑1.换到要进行编辑的子框图中,在边框上单击鼠标右键,在弹出的快捷菜单中选择<编辑本分支所处理的事件>选项,打开<编辑事件>对话框。
2.在<编辑事件>界面中可以对相应的事件源和事件进行定义,在左侧的<事件说明符>下面点击<添加事件>或者<删除>即可相应的改变事件数量。
在<事件源>和<事件>两个子窗口中分别选中相应的对象,左侧的<事件说明符>下面就会出现两者的组合,点击<确定>,此子事件框图就可以完成编辑。
LABVIEW 中的事件结构杂谈

LABVIEW中的事件结构杂谈刚开始接触事件结构时觉得它很好用,所以很喜欢用,但也引起了一些问题,就是前面板很容易就被挂起来了,就是所前面板没有响应了,很郁闷。
之后就不敢用了,很多可以用事件结构的地方都只用CASE结构麻烦的代替了~~今天被师兄那么一指点,觉得完全是委屈了事件结构啊,之前事件结构引起的问题可以很容易的解决。
方法就是设置“超时”(之前一直觉得这个东西没用的):一般情况下,事件结构是会和while循环套用的,通过不断的循环来执行不同事件源激发的事件,但如果不设置超时,也没有事件源发生,那么while循环将一直等待事件的发生而不进行循环,这样就会使得事件结构外的其他程序也不能执行,可能造成的结果就是前面板本该有反应的地方(比如变量值的变化)没有了反应。
而如果设置了超时,比如设置为100(ms),意思就是每隔100ms如果没有事件发生就超时,进行一次循环,那么事件结构外的其他程序也就得到了执行。
总结一下:如果事件结构在while循环中,而事件结构之外又有其他的程序需要执行(可能不依赖于事件的发生),那么就应该设置超时。
在事件处理过程内,如何响应前面板命令控件的命令? 我发现,在一个事件内的处理过程完成之前,系统不能响应前面板的其他命令。
系统是在事件完成之后的等待时期才响应其他前面板命令事件。
编辑事件结构对话框的下边有一个: 锁定前面板在事件分支执行完毕前。
你可这个默认选中的选项取消了,就可以实现你的“在一个事件过程处理中途响应前面板的其他命令"功能。
LabVIEW事件结构使用LabVIEW图形化语言开发的应用程序界面是图形化用户操作界面,也称为:GUI (graphical user interface),它的作用是与操作者实现人机对话形式的互动操作。
这种对界面操作的互动响应在LabVIEW 6.1发布之前,只能通过“轮询(polling)”的方式来实现。
轮询的方式的缺点是:需占用一定的CPU资源(在没有事件发生时)和灵活性不好。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
LabVIEW事件结构的妙用
首先,我们回顾一下上期节目:LabVIEW网络讲坛乊悬案迷思中关于事件结构的几个重要知识点。
事件结构的基本组成部分:
事件结构五大基本组成部分
事件结构由——事件选择器、超时接线端、事件数据节点、事件过滤节点和动态事件接线端5个基本部分组成。
事件结构编程的3条黄金原则:
在使用LabVIEW事件结构迚行编程的时候,我们应该注意:1.不要将事件结构放置在while循环乊外,而应该放置在while循环的内部;2.不要在事件结构的内部使用循环处理事件,可选择采用生产者消费者结构,在生产者循环中放置事件结构,在消费者循环中处理事件;3.记得为事件结构添加一个单独处理停止按钮的分支。
遵守以上三条原则将使我们的程序更加健壮,避免在使用事件结构的时候出现前面板死锁等问题。
过滤事件与通知事件:
在LabVIEW中,以问号结束的事件被称为过滤事件,其余的事件被称为通知事件。
对于通知事件,程序可以感知事件的发生并且响应该事件,然后再处理在事件结构中定义的任务;而对于过滤事件,程序感知事件发生后,首先处理在事件结构中定义的任务,然后根据事件过滤节点的值(Discard?)来决定是否响应该事件或是否改变事件数据。
因此我们建议,在希望参与处理用户操作时使用过滤事件,因为过滤事件可以放弃事件或修改事件数据。
如果仅需要知道并响应用户执行的某一特定操作,则应使用通知事件。
在本期节目中,我们着重介绍动态注册事件的用法。
静态和动态两种事件注册模式:
静态注册指定了事件结构的每个分支具体处理哪些事件。
一旦VI开始运行,LabVIEW将自动注册这些事件,并且在VI运行的整个过程中无法改变事件结构所处理的事件。
而动态事件注册与VI服务器相结合,允许在程序运行时使用控件、VI或应用程序的引用来动态地指定和改变产生事件的对象。
动态注册在控制LabVIEW产生何种事件和何时产生事件等方面更为灵活。
Demo 1和Demo 2帮助大家更好地理解动态注册事件编程方法。
Demo 1:动态注册事件_阿拉丁神灯.vi
Demo概述:
在这个VI中,用严格自定义的方式将一个布尔类型的控件做出神灯的样子,并为这个布尔控件动态注册了”鼠标按下”的事件。
这个事件执行的任务是显示神灯神仙,并弹出一个对话框。
由于该事件采用的是动态注册的方式,所以可以通过一个按钮取消对该事件的注册。
并通过另一个按钮再次注册该事件。
这就是动态事件的使用效果,它可以在程序运行的过程中,动态地控制何时注册事件和注册什么样的事件。
程序实现:
1.当我们选择动态注册事件的时候,首先需要在程序框图上放置一个“注册事件”函数;该函数位于:函数面板》对话框与用户界面》事件》注册事件。
2.接下来,在“注册事件”函数的事件源输入端上连接一个引用,该引用可以是控件、VI或应用程序的引用。
在阿拉丁神灯的程序中,事件源就是神灯所对应的布尔控件,所以我们为注册事件函数连接该布尔控件的引用。
3.单击事件源的向下箭头,可以选择该引用对应注册事件,例如:鼠标按下、鼠标迚入、值改变等等。
调整“注册事件”函数的大小,还可以选择另一个事件,从而为一个或多个引用注册多个事件。
4.在程序框图上“注册事件”函数的右侧是一个While循环,在循环中放置一个事件
结构。
右键单击事件结构的边框,从快捷菜单中选择显示动态事件接线端。
动态
事件接线端的左侧与“注册事件”函数的事件注册引用句柄相连,右侧与“取消注册
事件”函数的事件注册引用句柄相连。
“取消注册事件”的作用是彻底停止对事件的
响应,并释放相应的内存资源。
5.接下来,我们需要编辑事件结构的分支,以处理动态事件。
应该注意的是,要将某个事件分支配置为可动态处理的注册事件,必须从动态列表中选择所需的事件源,而不能从控件列表或其它列表中选择。
在阿拉丁神灯的程序中,动态注册的“神灯:鼠标按下”事件分支,执行的操作就是:显示神灯神仙对应的图片控件,并弹出对话框,当对话框关闭时,图片也随乊隐藏起来。
6.那么程序又是如何取消动态注册事件的呢?让我们来看一下“取消注册”的事件分支:同样是放置一个“注册事件”函数,将事件注册引用句柄与动态事件接线
端连接起来,将一个“非法引用句柄常量”赋给事件源接线端(该常量位于文件I/O》文件常量》非法引用句柄常量),此时,前一个“注册事件”函数对应的动态注册
事件将被取消。
7.在事件被取消后,如何再次恢复该事件呢,让我们一起来看看“注册”分支中的代码。
同样是放置了一个“注册事件”函数,将事件注册引用句柄与动态事件接
线端连接起来,将神灯控件的引用连接到事件源接线端。
这样,在按下了注册按
钮乊后,该事件将被重新注册。
Demo2:动态注册事件_鼠标拖曳.vi
Demo概述:
我们知道,在一个VI运行的过程中,前面板上控件的位置是静止的,不能像VI没有运行时那样,可以通过鼠标的拖动来改变控件的位置。
而动态注册事件,就能在VI运行的过程中,用鼠标拖动前面板控件,让控件的位置将随着鼠标的位置而移动。
在VI的前面板,有三张扑克牌,它们是三个图片控件。
在VI运行的过程中,用鼠标拖动这些控件,它们的位置将发生改变。
程序实现:
1.首先,仍然是在循环的外部放置“注册事件”函数,通过下拉该函数,创建3个事件。
其中,“鼠标按下”后面带一个问号为过滤事件,“鼠标移动”和“鼠标释放”为通知事件。
“鼠标移动”的事件源是当前的vi,所以我们将一个“通用VI
引用”连接到它的事件源输入端;“鼠标按下”和“鼠标释放”的事件源是前面板上的所有控件,所以我们通过两个属性节点,得到了所有控件的引用数组,并连接到“鼠标按下”和“鼠标释放”输入端。
2.再来看事件结构中几个事件分支的实现,首先是“鼠标按下”过滤事件,在该分支中,我们通过事件数据节点“控件引用”来获知鼠标拖动的具体是哪个控件,并将该控件的引用传递给移位寄存器。
3.接下来,在“鼠标移动”的分支中,通过事件数据节点“坐标”获取鼠标的位置,并把该坐标值赋给“鼠标按下”的控件,从而达到控件被鼠标拖动的视觉效果。
4.最后,在“鼠标释放”的分支中,通过“非法引用句柄常量”取消对“鼠标移动”事件的注册,从而实现在鼠标释放后,控件的位置不再跟随鼠标发生变化。
在某些情况下,不使用动态注册事件,而使用过滤事件,也可以实现鼠标拖曳动态显示的前面板效果,通过Demo 3迚行说明。
Demo 3:过滤事件_鼠标拖曳显示波形.vi
Demo概述:
前面板上有一个树形控件,树形结构的最顶层是信号,下面是正弦波、方波、锯齿波、三角波四种类型。
运行这个VI,用鼠标拖动文字,放入波形图表,图表中则
显示相应的波形。
程序实现:
在程序中,我们用到了“拖曳开始”的过滤事件,和它对应的“数据”和“拖曳模式”两个事件过滤节点。
1.首先,用一个条件结构判断鼠标拖动的是哪种信号对应的字符串,已产生对应的波形数据。
由于事件过滤节点——“数据”定义的类型是簇数组,并且每个簇元素都是字符串和变体的组合,所以我们将波形数据转换为变体数据,并跟字符串“waveform”捆绑起来,通过事件过滤节点迚行传递。
2.在“波形图表:拖曳输入”分支中,判断拖曳到波形图表的是否是有效值,是则通过事件过滤节点接受;如果不是,则数据将被丢弃,而不做任何处理。
3. 在“波形图表:放置”分支中,依然是先判断放置到波形图表的是否是有效值,如果是,则通过“获取拖放数据”(该函数位于应用程序控制》获取拖放数据)将数据提取出来,在波形图表中显示。
如果数据无效,则丢弃不做任何处理。
总结
在本期的节目中,我们首先回顾了上期节目“事件结构乊谜”中的几个重要知识点。
然后,我们通过阿拉丁神灯和鼠标拖动扑克牌的两个范例程序,介绍了动态注册事件的用法。
当我们希望事件只发生在应用程序的某些部分,或在程序运行的过程中,可以动态改变发生事件的控件或VI时,就需要用到动态注册。
动态注册在控制LabVIEW产生何种事件和何时产生事件等方面更为灵活。
接下来,由鼠标拖动扑克牌引伸出鼠标拖动显示波形的应用,虽然该应用基于静态事件注册,而非动态注册;但过滤事件的巧妙使用,使得我们仍然可以获得动态的用户事件效果。
在LabVIEW事件结构的高级应用中,我们还会学习到用户自定义
事件、ActiveX事件以及.Net事件的使用方法,敬请关注。