如何使控制栏在Tcl / Tk中循环播放

问题描述

我需要您的帮助,以创建一种能够控制联系的方式:

  • 播放|暂停|停止

只有我无法使用播放暂停方法制作脚本。只需使用“ break”方法停止太容易了。

示例代码

set waitvar 0

for {set i 0} {$i < 100} {incr i} {
  puts "$i"
  after 1000 set waitvar
  waitvar vwait 
  set waitvar 0
}

如果有人可以在Tcl / Tk中提供一些教学示例来帮助我。

从现在开始,我很感激。

如果可以举一个例子的人是Tcl:

使用switch。像这样。

set pause "pausing"

switch pausing 
  $play {expr {1}} 
  $pause {expr {2}} 
  $stop {expr {3}}

现在,如果谁来在Tk中举一些例子:

通过按钮拨打电话,以便于理解。

并不一定要举两个例子,我只是建议两个例子之一-Tcl或Tk

注意-对于这个问题的答案,我需要在Tcl / Tk 8.5版本中给出

解决方法

在8.5及更低版本中,最好使用异步编程。这就需要与您所使用的方法完全不同的方法(这与8.6及更高版本的协程相似)。这是您所需步骤的示意图;实现暂停的最简单方法是在暂停时不增加状态变量。

proc UpdateWaitvar {} {
    global waitvar callback paused
    if {$paused} {
        set callback [after 100 UpdadteWaitvar]
    } elseif {[incr waitvar] < 100} {
        set callback [after 1000 UpdateWaitvar]
    }
}

proc CancelWait {} {
    global callback
    after cancel $callback
}

proc StartWait {} {
    global waitvar callback paused
    set waitvar 0
    set paused 0
    set callback [after 1000 UpdateWaitvar]
}

proc TogglePause {} {
    global paused
    set paused [expr {! $paused}]
}

与此相关的尴尬之处在于,您将“循环”编写为代码块,并在您暂停和让其他事情发生的部分之间运行,这似乎不是一种自然的工作方式。 / p>

waitvar变量绑定到GUI上显示进度的所有操作留给您。


8.6方法

对于8.6,您可以改用协程。

proc StartWait {} {
    coroutine waiter apply {{} {
        global waitvar paused callback
        set paused 0
        for {set waitvar 0} {$waitvar < 100} {incr waitvar} {
            set callback [after 1000 [info coroutine]]
            while {$paused} {
                set callback [after 100 [info coroutine]]
            }
        }
    }}
}

proc CancelWait {} {
    global callback
    after cancel $callback
    rename waiter {}
}

# Also same TogglePause as before; it is,after all,just setting the right variable