2016-06-05 3 views
0

В 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 БЕЗ предыдущего показания времени?

ответ

3

Основная проблема у вас есть то, что глобальная переменная systemTime не держат в курсе фактического системного времени. Нам нужно либо напрямую переключиться на использование [clock seconds], либо нам нужно добавить небольшую рабочую «задачу», чтобы обновить переменную. Вот последний вариант:

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

Это будет поддерживать переменную ток и может быть просто добавлено в ваш текущий код просто. Хотя вы можете сделать лучше и сделать так, чтобы текущее отображение времени также автоматически обновлялось. Делать это легко требует -textvariable опции к ttk::label (и многие другие виджеты поддерживают его, а):

proc updateTheTime {} { 
    global systemTime displayedTime 
    set systemTime [clock seconds] 
    set displayedTime [clock format $systemTime -format "%T"] 
    after 500 updateTheTime 
} 
updateTheTime 

# ... 

ttk::label .time -textvariable displayedTime 

Это все, что требуется, чтобы сделать активный графический интерфейс; виджет автоматически заметит измененную переменную и сам обновит (он использует тот же механизм, который поддерживает переменные трассы Tcl). Обновление каждые полсекунда настолько дешево в вычислительных терминах, что вы его не заметите, за исключением того факта, что временная метка будет обновляться. Хотите, чтобы виджет показывал что-то еще? Просто измените код, который генерирует значение в переменной.

+0

Можно использовать события 'after' и переменную' trace' для выполнения гораздо более сложных задач, но большую часть времени вы можете делать отличные вещи с очень простым кодом. –

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 

Ссылка:update, after

Смежные вопросы