Tcl Tk GUI没有响应

Tcl Tk GUI没有响应,tcl,tk,Tcl,Tk,有人能帮我解决这个问题吗?我正在尝试制作一个GUI,用于画布中所有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<=$g

有人能帮我解决这个问题吗?我正在尝试制作一个GUI,用于画布中所有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
包裹需要数学
过程更改颜色{rM gM bM}{
对于{set r 0}{$rTk(和Tcl)来说,在500
之后的同步
期间,它根本不处理任何事件。它只是在500毫秒内停止处理

您需要改为处理该时间的事件。将500之后的
替换为:

after 500 {set go_on yes}
vwait go_on
请注意,
go\u 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
proc changeColor{rM gM bM}{

对于{set r 0}{$rTry在第二行之前使用update-idletasks。你好,Mario,非常感谢你的帮助。它可以工作。
update-idletasks
看起来可以工作,但是如果你做了一些生成外部事件的事情,例如移动或调整窗口大小,它就会出现问题……你好,多纳尔,非常感谢你的详细说明。