首页 > 解决方案 > 如何使控制栏在 Tcl/Tk 中循环

问题描述

我需要你的帮助来创建一种能够控制键的方法:

只有我无法使用Play & Pause方法制作脚本。Just Stop太容易了,使用“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 提供它

标签: loopsfor-loopcontrolstcltk

解决方案


在 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}]
}

尴尬的一点是,您将“循环”编写为代码块,在您暂停的部分之间运行并让其他事情发生,这感觉不是一种自然的工作方式。

将变量绑定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

推荐阅读