Tk GUI没有响应

时间:2016-10-06 13:48:52

标签: tcl tk

有人可以帮我解决这个问题吗?我正在尝试制作一个用于画布中所有RGB矩阵的颜色演示的GUI。不幸的是,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

Code_Snapshot

GUI_Snapshot

1 个答案:

答案 0 :(得分:2)

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