Tk GUI 没有响应
Tk GUI Not Responding
有人可以帮我解决这个问题吗?我正在尝试制作一个 GUI,用于 canvas 中所有 RGB 矩阵的颜色演示。不幸的是,GUI 没有响应,并且在循环完成之前它不会按预期更改颜色。有什么问题吗?如果我在循环中配置一个小部件,我经常会遇到这个问题。
package require Tk
package require math
proc changeColor {rM gM bM} {
for {set r 0} {$r<=$rM} {incr r} {
for {set g 0} {$g<=$gM} {incr g} {
for {set b 0} {$b<=$bM} {incr b} {
set rHex [format %02X $r]
set gHex [format %02X $g]
set bHex [format %02X $b]
set mark #
set color [append mark $rHex $gHex $bHex]
.cv config -bg $color
.lb config -text "[format %03d $r] [format %03d $g] [format %03d $b]"
after 500
}
}
}
}
canvas .cv
ttk::label .lb
ttk::button .bt -text Run -command {changeColor 255 255 255}
grid .cv -row 0 -column 0 -sticky news
grid .lb -row 1 -column 0 -sticky we
grid .bt -row 2 -column 0
Tk(和 Tcl)在同步 after 500
期间根本不处理任何事件。它只是 停止了那 500 毫秒的过程。
您需要改为处理那个时间的事件。将 after 500
替换为:
after 500 {set go_on yes}
vwait go_on
请注意 go_on
是全局的,这可能会导致代码重入问题。当您的代码为 运行.
时,您需要禁用运行该过程的按钮
或者您可以使用 Tcl 8.6 并将所有内容转换为协程。然后你就可以进行异步睡眠而不会有填满堆栈的危险:
proc changeColor {rM gM bM} {
for {set r 0} {$r<=$rM} {incr r} {
for {set g 0} {$g<=$gM} {incr g} {
for {set b 0} {$b<=$bM} {incr b} {
set rHex [format %02X $r]
set gHex [format %02X $g]
set bHex [format %02X $b]
set mark #
set color [append mark $rHex $gHex $bHex]
.cv config -bg $color
.lb config -text "[format %03d $r] [format %03d $g] [format %03d $b]"
####### Notice these two lines... ########
after 500 [info coroutine]
yield
}
}
}
}
##### Also this one needs to be altered #####
ttk::button .bt -text Run -command {coroutine dochange changeColor 255 255 255}
# Nothing else needs to be altered
有人可以帮我解决这个问题吗?我正在尝试制作一个 GUI,用于 canvas 中所有 RGB 矩阵的颜色演示。不幸的是,GUI 没有响应,并且在循环完成之前它不会按预期更改颜色。有什么问题吗?如果我在循环中配置一个小部件,我经常会遇到这个问题。
package require Tk
package require math
proc changeColor {rM gM bM} {
for {set r 0} {$r<=$rM} {incr r} {
for {set g 0} {$g<=$gM} {incr g} {
for {set b 0} {$b<=$bM} {incr b} {
set rHex [format %02X $r]
set gHex [format %02X $g]
set bHex [format %02X $b]
set mark #
set color [append mark $rHex $gHex $bHex]
.cv config -bg $color
.lb config -text "[format %03d $r] [format %03d $g] [format %03d $b]"
after 500
}
}
}
}
canvas .cv
ttk::label .lb
ttk::button .bt -text Run -command {changeColor 255 255 255}
grid .cv -row 0 -column 0 -sticky news
grid .lb -row 1 -column 0 -sticky we
grid .bt -row 2 -column 0
Tk(和 Tcl)在同步 after 500
期间根本不处理任何事件。它只是 停止了那 500 毫秒的过程。
您需要改为处理那个时间的事件。将 after 500
替换为:
after 500 {set go_on yes}
vwait go_on
请注意 go_on
是全局的,这可能会导致代码重入问题。当您的代码为 运行.
或者您可以使用 Tcl 8.6 并将所有内容转换为协程。然后你就可以进行异步睡眠而不会有填满堆栈的危险:
proc changeColor {rM gM bM} {
for {set r 0} {$r<=$rM} {incr r} {
for {set g 0} {$g<=$gM} {incr g} {
for {set b 0} {$b<=$bM} {incr b} {
set rHex [format %02X $r]
set gHex [format %02X $g]
set bHex [format %02X $b]
set mark #
set color [append mark $rHex $gHex $bHex]
.cv config -bg $color
.lb config -text "[format %03d $r] [format %03d $g] [format %03d $b]"
####### Notice these two lines... ########
after 500 [info coroutine]
yield
}
}
}
}
##### Also this one needs to be altered #####
ttk::button .bt -text Run -command {coroutine dochange changeColor 255 255 255}
# Nothing else needs to be altered