tcl/tk详解——after、update和vwait

 

http://blog.csdn.net/dulixin/archive/2008/05/04/2383555.aspx

1、after

after主要用于要延迟一段时间再执行脚本,update主要用于处理挂起的事件和回调,vwait可以跟踪一个变量的修改。

名称
after - 等待一段时间后再执行命令

语法
after ms
after ms ?script script script ...?
after cancel id
after cancel script script script ...
after idle ?script script script ...?
after info ?id?


描述
这个命令用来延迟程序执行或者在后台执行命令,它有几种形式,取决于这个命令的第一个参数:

after ms
Ms必须是个整型数据,以毫秒为单位。这个命令是休眠ms毫秒后返回。当这个命令在休眠的时候应用程序不想赢任何事件。
after ms ?script script script ...?
这种形式的命令直接返回数值,但是会在ms毫秒后把一个Tcl命令作为事件处理来运行。这个命令在给出的时候就会被立刻执行.延迟命令就像concat命令格式的风格被连接起来,这个命令将在全局运行(脱离所有Tcl进程的上下文)。当运行延迟命令时产生错误就使用interp bgerror机制来报告错误。after命令返回一个可以使用after cancel来取消延迟命令的ID。
after cancel id
取消运行之前已经确定要运行的延迟命令。id指出了哪个延迟命令会被取消,之前必须有一个after命令返回的id。如果给出id的命令已经运行那么after cancel就没有作用。
after cancel script script ...
这个命令也可以取消一个延迟命令的执行,这个script参数被使用空格分隔连接在一起(就像concat命令的风格),如果有一个没有执行的命令和要取消的命令相同,这个命令就被取消运行,如果没有和要取消命令相同的命令那么after cancel就没有作用.
after idle script ?script script ...?
把script参数使用空格分隔连接在一起(就像concat命令的风格),并且当空闲回调后安排最终的脚本稍后会被执行。这个脚本会立刻运行,接着会进入事件循环而且进程中没有事件。这个命令返回一个可以使用after cancel取消的延迟命令ID。当运行延迟命令时产生错误就使用interp bgerror机制来报告错误。
after info ?id?
这个命令返回当前存在的事件句柄。如果没有id参数没有提供,这个命令返回所有被after命令创建的事件句柄。如果提供了id,指定一个存在的句柄,这个句柄必须是之前使用after命令返回的参数而且必须不能已经触发或者取消。这个命令返回一个包含两个元素的列表,第一个元素是命令相关的id,第二个元素指示事件句柄类型是idle还是timer。
after ms和after idle形式的命令假定应用程序是事件驱动的,直到应用程序进入了事件循环,延迟命令才会被执行.在不是一般事件驱动的应用程序当中,比如tclsh,可以使用vwait或者update命令进入事件循环.

示例
这个例子定义了一个命令使tcl空闲N秒:

proc sleep {N} {   after [expr {int($N * 1000)}]}
下面的脚本使wake_up在8个小时后运行(在这个时间事件循环被激活):

after [expr {1000 * 60 * 60 * 8}] wake_up
下面的命令可以被用于一步一步地方式做长时间运行的计算(就像这里描述的::my_calc::one_step,假设返回一个布尔数值来标志其它的步骤是否在执行).既然计算本身需要被排序所以可以逐步工作.这个技巧在使用的时候需要十分小心,需要避免事件循环杯进程管理给饿死(当下一个步骤去做一个已经触发的时间事件时正好事件队列被耗尽),在你做一个很慢的任务时,想确认一个TK GUI是否还有响应的时候非常有用.

proc doOneStep {} {   if {[::my_calc::one_step]} {      after idle [list after 0 doOneStep]   }}doOneStep

after有几种形式,使用比较灵活。
    最简单的形式,间隔一定时间后再运行脚本:
    % after 5000
    上面的命令就是间隔5秒钟后再继续运行脚本,这在等待其它设备处理时比较有效。
   
    间隔一段时间后执行一条命令:  
    % set a a
    a
    % after 5000 set a b
    after#1
    间隔5秒钟后执行命令set a b,如果等待5秒钟后再查看$a的值就变成b了。需要注意的是,在tcl中,时间循环并没有开启,而tk中事件循环总是活动的,所以在tcl脚本中使用时需要非常小心,可能你需要的值在5秒钟后并没有改变,这里就需要使用到两个命令update和vwait,update命令可以时解释器去处理挂起的事件,vwait可以等待一个变量到修改为止,下面举例说明:
    如果在5秒钟之后使用查看变量a里面的值:
    % puts $a
    a
    还是a,并没有修改为b,那么这个时候使用update:
    % update
    % puts $a
    b
    上面的方法可能在实际使用时并没有意义,也许脚本的编写者是想在tcl中精确的控制脚本的执行时间,那也没有问题,可以使用vwait来操作,在时间间隔的期限内使用vwait可以使命令在精确的时间间隔时执行:
    % set a a
    a
    % after 5000 set a b
    after#1
    % vwait a
    %
    会等待到第5秒钟执行赋值命令。
 
 
    如果注册了一条命令在某个时间执行,也可以取消这个命令的执行,使用after cancel命令,这个命令有两种形式,既可以输入要取消命令的ID,也可以使用该命令本身来取消。
    如想要取消ID为after#1的命令:
    % after cancel after#1
    如果ID为after#1的命令存在就去掉这个命令的注册,如果不存在就什么都不发生。
    取消一个命令体:
    % after 5000 set a c
    after#2   
    % after cancel set a c
    以上命令就会取消set a c的事件注册,如果不存在这个命令就什么都不发生。
 
    显示目前注册的after事件或者某个after事件的详细信息:
    直接使用after info命令来显示所有的after事件:
    % after 5000 set a b
    after#1
    % after 5000 set a c
    after#2
    % after info
    after#2 after#1
    如果需要知道after事件的详细信息,就需要使用具体的事件ID:
    % after info after#1
    {set a b} timer

2、update

名称
update - 处理挂起的事件和空闲回调

语法
update ?idletasks?


描述
这个命令用来给应用程序“更新”,进入事件循环直到所有挂起的事件和空闲回调都执行完毕。

如果指定idletasks,就不处理新的事件或错误,只有空闲回调被调用,这就导致操作被延迟了,就像显示更新和窗口设计,会被立刻执行。

当应用程序的状态发生变化和需要这些变化立刻显示时update idletasks命令是非常有用的,不用等待到脚本完成。多数显示更新被当作空闲回调来执行,所以update idletasks可以使它们运行。但是这里有一些更新只能在事件响应中发生,像窗口尺寸变化触发等,这些更新不会在update idletasks中发生。

当运行一个长的运算但是仍然想和应用程序交互时,update命令在脚本中非常有用。

示例
运行一个循环约一秒钟后停止:

set x 1000

set done 0

after 1000

set done 1

while {!$done} {  

  #一个无聊的例子   

set x [expr {log($x) ** 2.8}]

#测试时间是否到   

update

}

3、vwait

名称
vwait - 一直等待直到一个变量被修改为止

语法
vwait varName


描述
这个命令进入Tcl事件循环,Tcl将会一直处理事件直到变量varName被修改为止,一旦varName被修改了,vwait命令将会立刻返回,varName必须是一个全局范围变量。(要么是一个全局变量,要么带有完全的名字空间路径)。

在一些情况下在varName被修改后vwait命令可能不会立刻返回,如果设置varName的事件句柄没有完成,那么vwait命令就不会立刻返回。例如,如果一个事件句柄设置varName,然后它自己调用vwait去等待一个不同的变量,这样的话有可能需要经过长时间后才能返回。在这种情况下最高堆栈层的vwait命令阻塞,等待事件句柄完成,所以不能返回。

示例
运行事件循环直到一些事件调用exit。

vwait forever
在连接一个服务器套接字时等待5秒钟,否则关闭套接字继续运行脚本。

# Initialise the stateafter 5000 set state timeoutset server [socket -server accept 12345]proc accept {args} {   global state connectionInfo   set state accepted   set connectionInfo $args}

# Wait for something to happenvwait state

# Clean up events that could have happenedclose $serverafter cancel set state timeout

# Do something based on how the vwait finished...switch $state {   timeout {      puts "no connection on port 12345"   }   accepted {      puts "connection: $connectionInfo"      puts [lindex $connectionInfo 0] "Hello there!"   }}

标签: Tcl/Tk
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vivado是一款由Xilinx开发的集成电路设计软件。Tcl是Vivado中使用的一种脚本语言,可以用于对文件进行操作、对字符串进行处理等。通过使用Tcl脚本,可以实现对Vivado软件的各种功能进行自动化控制和扩展。 要在Vivado中获取Tcl的帮助信息,可以使用命令"help"。在Tcl命令行或者Tcl脚本中,输入"help"命令将显示Tcl的帮助文档,其中包含了Tcl的命令列表以及每个命令的说明和用法。 在Vivado中,可以通过在Setting中的综合、实现、生成比特流设置中添加tcl.pre和tcl.post的路径,来插入自己的Tcl脚本。这样,在执行相应的流程之前或之后,Vivado会自动执行这些Tcl脚本。通过编写Tcl脚本,可以实现自定义的流程控制和功能扩展。 关于如何编写Tcl脚本的方法,可以参考Tcl的语法规则和命令使用。Tcl脚本由一系列命令组成,可以使用变量、条件语句、循环结构等来实现复杂的逻辑操作。可以通过学习Tcl的基本语法和查阅相关资料来掌握Tcl脚本的编写方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [在vivado中使用tcl脚本(UG894)](https://blog.csdn.net/qq_42322644/article/details/122791274)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值