我无法修复spinbox的奇怪行为。具体地说,我需要通过在其中使用-command和update来更新图形用户界面来更改微调框的值。
代码略有简化,如下所示:
package require Tk
set sv 1
ttk::spinbox .sp -from 1 -to 9 -textvariable ::sv \
-command {
after 50 ;# some processing imitated
puts [incr ::tmp]:$::sv ;# changes shown in CLI - ok
update ;# changes shown in GUI - ???
}
pack .sp问题是,当点击旋转框的箭头(更多的是“向上”而不是“向下”,但我没有发现其中有任何规律性),然后按下10-20秒,旋转框就会进入无限的更新周期,如puts所示。
当然,原因是-command代码中的update,但我不能没有它。
在Windows (Tk 8.6.8)和Linux (Tk 8.6.10),ttk::spinbox和spinbox上试用过,都暴露出了这种怪癖。
有什么方法可以克服这个问题吗?非常感谢你的帮助。
发布于 2020-11-18 18:44:48
通常,不要从update回调中更新-command变量,尤其是不要从-command 回调中运行。 You probably shouldn't do that at all.该命令允许处理事件(它运行一个辅助事件循环,直到事件队列被排出),它正是问题的根源。(我还建议不要使用update idletasks;这将触发问题的核心所在的重新配置和重新绘制。)
相反,只要停止运行命令回调即可。这会将控制权返回给Tk小部件,而Tk小部件又会返回到主事件循环。还建议您不要在回调中进行大量处理,而是将此类处理安排在以后进行。具体如何做到这一点可能很复杂,而且肯定是特定于应用程序的。稍后移动处理的一种方法是将其转移到在after事件中运行的过程,如下所示:
package require Tk
set sv 1
proc updateVar {varName} {
upvar "#0" $varName var
after 50; # Processing...
incr var; # Actually update the variable
}
ttk::spinbox .sp -from 1 -to 9 -textvariable ::sv \
-command {after 0 updateVar ::sv}
pack .sp请注意,这不会调用update。更实质性的代码延迟可能涉及线程或子进程。正如我所说的,做好这件事可能很复杂。尤其是当鼠标按键按下时对图形用户界面布局的更改导致所选值的更改,进而导致对图形用户界面布局的更改,这会导致…
发布于 2020-11-19 17:54:38
我制作this archive with video是为了演示在其-command选项中包含update时,spinbox的奇怪行为。
归档中有两个测试:
test1.tcl提供了一种不应该这样做的方法。有两个问题:
-command代码移到单独的代码中,而是立即从-command代码中触发
结果可以在test1-spx.mp4:中看到,当按下旋转框箭头10-20秒时,旋转框进入无限的更新周期。这种行为是不正常的,尽管当焦点切换到另一个应用程序时很好地揭示了这一点。
test2.tcl提供了一种克服这种怪癖的方法。after idle用于推迟更新。您也可以使用after 0来实现这一点。
在“真正的测试”test2_pave.tcl中,我对-command使用了以下过程
proc fontszCheck {} {
lappend ::afters [after 0 {
foreach a $::afters {after cancel $a}
set ::afters [list]
::t::toolBut 4 -3
}]
}希望这些信息对处理Tk spinbox有用。
https://stackoverflow.com/questions/64890841
复制相似问题