事件日常实例
我们在电脑上操作键盘鼠标时,实际上是产生了一个个事件,系统响应这些事件并执行相应功能。
事件全称为事件驱动程序设计(Event-driven programming),用户点击鼠标键盘,点击界面或界面上的控件,一个控件或变量的值改变在程序里都称之为事件,这些动作的发生都是由程序员自行决定。程序最初设计出来是批处理(batch)执行的,即执行完一条执行下一条,初学者学习编程语言编写的程序都是这种类型。事件最终目的是(modelless),即消除设计模式。
LabVIEW中有三种事件结构
1一般事件结构
2回调事件结构
3注册事件结构
一般事件结构是基本技能,必须掌握,重点掌握自定义事件和注册事件结构,回调事件一般是用在于.NET交互比较多,这个只做了解。
1一般事件结构
一般事件结构包括鼠标点击、键盘按键按下、控件点击或值改变、VI的各种事件和菜单事件等,事件一般配合while循环一起使用,否则程序只执行一次就退出。
创建一个工程命名为Event
创建一个VI命名为Common Event
在程序里放置一个事件结构
在事件结构上右击会弹出下拉菜单点击添加事件
选择不同的事件源会有不同的事件列表
在前面板放置一个按键,再次执行上述操作,我们可以看到事件源列表框中添加了新的事件源,事件源就是本VI的对象或VI本身的事件汇总。
2一般事件结构实例
创建一个VI命名为Menu Event
1、前面板关事件
在程序中放置一个循环和一个事件结构,选取VI->前面板关闭?事件
在事件中放置一个双按钮对话框。对话框消息为“是否关闭前面板”
以下是运行效果
事件具有以下特点
1一个事件只能触发事件框图的一个分支,事件框图的一个分支可以接受多个事件触发。
2事件是多播的,同一个事件可以被多个事件框图执行,例如一个停止按钮值改变,可以关闭多个包含事件的循环。
2、用户菜单事件
打开VI菜单编辑->运行时菜单,选择自定义。
按照下图图编辑完后保存定义菜单即可
在事件框图右键添加事件,选择菜单选择(用户)
在将项标识符通过单按钮对话框显示出来,实际程序中会根据不同的项标识符来。
具体运行结果如下;
回调事件结构
经过测试LabVIEW系统当前能识别的事件全都可以回调,在很多资料里都将回调讲的晦涩难懂,其实大本不必那么为难,经过本章的讲解,你会觉得回调不过如此。
经过归纳回调有以下4种形式:
1net回调
2ActiveX回调
3一般事件回调
4注册事件回调
回调函数其实只关心两个函数
1事件回调注册
1.1事件源引用:输入还有事件源的引用,并选择事件源的具体事件;
1.2用户参数:回调事件时注入的参数,一般为控件引用,事件反生后将值赋值给控件引用;
1.3VI引用:在输入1.1和1.2后右键创建回调函数,在回调函数中编辑回调触发后执行的代码。
事件回调注册等效于一个异步动态调用的动态注册事件,具体等效模型描述如下:
2取消注册事件
这个功能比较单一,就是销毁回调事件引用。
回调函数范例:
1net事件回调
.net回调一般是。Net程序集中的类包含的事件,如果要使用该事件就必须使用回调函数。
这个例子我们使用LabVIEW自带范例
在帮助-查找范例-输入回调,选择下图的回调范例双击。
DataWatcher类中只有一个DoubleVale属性值改变事件,在旋钮值改变时,将旋钮值设置DataWatcher的属性DoubleVaue,此时触发回调事件,当前将仪表的引用设置到注册回调事件中。
下边看看回调函数,如下图,当触发回调函数时将值传递给仪表
下边演示下效果:
一般事件回调
下边用旋钮改变事件来赋值量表演示一般事件回调实现上面NET同样的功能。
1创建一个VI命名为CommonCallBack
2前面板放置一个仪表和一个旋钮并创建引用
3程序框图放置回调注册事件,将旋钮的引用设置到回调事件上,选择值改变事件,仪表的引用设置到回调函数值输入。
在VI引用右键选择创建回调函数,命名为CommomCallbackSub然后保存。
如下图使用属性节点读取上面控件的值并设置到下边的控件中并保存然后关闭。
打开CommonCallBack,在程序框图中添加循环和取消注册事件
下边运行看看效果:
用户注册事件回调:
下边用用户注册事件回到实现面同样的效果,过程不再详细描述。
程序框图如下图:
下边是回调函数程序框图:
下边运行看看效果,基本达到相同效果:
4ActiveX回调事件
由于ActiveX组件一般都很复杂,熟练使用一个需要花费大量的事件掌握其属性方法和事件,这个只使用LabVIEW自带范例讲解下。
在帮助-查找范例-输入回调,选择下图的回调范例双击。
这个的范例的主要功能是输入网址登录网页,当网页的标题改变时在网页标题字符控件中显示网页标题,
具体运行效果如下:
3注册事件结构
注册事件主要的目的是执行用户自定义的事件,也可以执行通用事件,通过事件引用将注册的事件传递出去,在其它线程中触发被注册的事件,这个用法在Actor Framewrok中经常用到。
注册事件用到的函数如下图:
1创建用户事件
1.1用户数据类型为任意数据,数据必须带标签,标签名为注册事件名称,要不然注册时会报错,
1.2用户事件输出:将事件变成数据流,传递到其它的循环或线程中。
2注册事件
一般注册事件和事件结构联合使用,典型的使用结构如下图,将产生的用户事件连接到注册事件端,然后将注册事件引用传递到事件的动态输入端。
2.1事件源:可以是一般事件也可以是用户自定义事件,不支持.NET和ActcivX事件。
3产生用户事件
当事件数据输入时会触发一个用户事件,并在注册的事件结构中执行,事件数据也会被传递到被注册的事件结构中。
4销毁用户事件
销毁当前输入的用户事件引用句柄,释放其占用的内存。
5取消注册事件
销毁当前输入的注册事件引用句柄,释放其占用的内存。
6清空事件队列
清空前事件队列中的数据,这个控件试用频次较低,只做了解就行。
用户事件范例,我们还是以生成消费者范例来说明用户事件用法。
事件的使用步骤
1创建用户事件
2注册用户事件
3编写用户事件分支的代码
4添加用户事件触发事件分支代码
5触发用户事件
6软件退出时销毁用户事件和动态注册事件引用
注意:上叙步骤中创建用户事件总是在最前面,先创建后使用,记住这一条就不会出错,销毁用户事件和动态注册事件引用是避免内存泄漏。
1一般注册事件范例
我们用一般注册事件实现上面仪表盘的操作
1.1创建一个VI命名为CommonRgisterEvent。
1.1放置事件结构、循环结构、动态注册事件和销毁动态注册事件4个控件并连线,结果如下图:
1.3前面板放置仪表盘、旋钮和停止控件,并创建旋钮引用。
1.4将旋钮引用连接到注册事件,点击事件选择值改变事件。
1
1.5添加按键值改变事件放置一个布尔真常量连接到停止端。
1.6
1.6添加动态事件并将值传递个仪表盘。
1.7运行如下图结果:
2用户注册事件范例
下边写一个数据采集、显示、分析和保存的例子,和队列章节实现相同功能,以上4个功能都在不同的线程中执行,具体实现过程如下:
2.1创建一个VI命名为Event Product and Cost
2.2创建4个用户事件如下图,其中Stop用于停止所有循环,其它的名字顾名思义。
2.3创建一个簇将以上用户事件进行捆绑。
2.4创建一个带循环的事件结构,放置动态注册事件和取消注册事件,如图连线。
将
2.5将事件簇解困stop连接到用户事件端,并在事件框图中添加事件,如下图操作。
2.6将右边的结构复制三分,并如图连线。
2.7从上到下第二个用户事件解困WaveDsp并接入用户事件,前面板添加波形图表控件并连线。
2.8从上到下第三个用户事件解困WaveDsp并接入用户事件,前面板添加波形图控件,添加频谱分析并连线。
2.9从上到下第四个用户事件解困Save并接入用户事件,在相应事件分支里保存事件数据。
2.10在前面板放置三个控件,如下图:
2.11在最上面事件结构中添加Run和Pause事件:
2.12在控件Stop中添加值改变事件
2.13在超时事件中添加正弦波产生代码,并设置到三个事件中:
2.14最后销毁所有的用户事件引用:
2.15最终的代码框图如下:
2.16运行代码看看运行结果:
不知道有么有读者观察到,上面用了事件多播的特性来停止所有事件,是否利用这一特性来简化下代码呢?