Tcl自动更新时钟

时间:2016-06-05 21:30:51

标签: tcl

在tcl中,我做了以下简单的登录程序。

package require Tk

wm geometry . "150x125"

set systemTime [clock seconds]

ttk::entry .loginUser
ttk::entry .loginPass -show "*"
ttk::label .l -text "Username:"
ttk::label .l2 -text "Password:"
ttk::button .b -text "Login"

pack .l
pack .loginUser
pack .l2
pack .loginPass
pack .b

bind . <Return> ".b invoke"

proc CheckLogin {} {
  if {[.loginUser get] eq "None"} {
    if {[.loginPass get] eq "1234"} {
      destroy {*}[winfo children .]
      ttk::label .time -text [clock format $::systemTime -format %T]
      ttk::button .b -text "Check time" -command {
        .time configure -text [clock format $::systemTime -format %T]
        pack .time
      }
      pack .b
    }
  }
}

.b configure -command CheckLogin

使用此程序,登录后,您将看到一个按钮:检查时间。当按下按钮时,它给出一个时钟,显示时间为%H%M%S,%H为小时,%M为分钟,%S为秒。但是,单击该按钮时,时间显示一次,并且不会更改。我的问题是,有没有办法让时钟自动更新,比如14:29:1到14:29:2没有前一次显示?

2 个答案:

答案 0 :(得分:4)

您遇到的主要问题是systemTime全局变量未与实际系统时间保持同步。我们需要直接切换到使用[clock seconds],或者我们需要添加一个小工作人员“任务”以使变量保持最新。这是后一种选择:

proc updateTheTime {} {
    set ::systemTime [clock seconds]
    after 500 updateTheTime
}
updateTheTime

这样可以保持变量的最新状态,并且可以简单地添加到当前代码中。虽然你可以做得更好,并使其当前时间显示也自动更新。这样做很容易需要-textvariable的{​​{1}}选项(以及许多其他小部件也支持它):

ttk::label

创建活动GUI所需的全部内容;小部件将自动注意到已更改的变量并自行更新(它使用与Tcl的变量跟踪相同的机制)。每半秒更新一次在计算方面是如此便宜,以至于你不会注意到它,除了时间戳将要更新的事实。想让小部件显示其他内容吗?只需更改在变量中生成值的代码。

答案 1 :(得分:1)

我们每次都必须使用clock seconds,以便我们可以准确地获取当前时间。在您的情况下,您使用::systemTime来访问时间,但它是静态的,因为它是在程序开始时获得的。

如果您已经使用过

 ttk::label .time -text [clock format [clock seconds] -format %T]

然后,每次单击按钮时,您都可以获得当前时间。

我添加了一个循环来获取当前时间,间隔为500毫秒,并且有一个按钮可以停止更新update命令在其中放置角色的时间。

package require Tk

wm geometry . "150x125"

set systemTime [clock seconds]

ttk::entry .loginUser
ttk::entry .loginPass -show "*"
ttk::label .l -text "Username:"
ttk::label .l2 -text "Password:"
ttk::button .b -text "Login"

pack .l
pack .loginUser
pack .l2
pack .loginPass
pack .b

bind . <Return> ".b invoke"
set ::done 0
proc CheckLogin {} {
  if {[.loginUser get] eq "None"} {
    if {[.loginPass get] eq "1234"} {
      destroy {*}[winfo children .]
      ttk::label .time -text [clock format [clock seconds] -format %T]
      ttk::button .b -text "Check time" -command {
        .time configure -text [clock format [clock seconds] -format %T]
        pack .time  
        puts "init done : $::done"  
        while {!$::done} {
            .time configure -text [clock format [clock seconds] -format %T]
            after 500 
            update 
        }
      }
      pack .b
      ttk::button .stop -text "Stop Updating" -command {
        after 100 {
            puts "user stopped the time update"
            set ::done 1
        }
      }
      pack .stop
    }
  }
}


.b configure -command CheckLogin

参考: updateafter