Tcl 画布小部件在调整大小后大小错误

Tcl 画布小部件在调整大小后大小错误,tcl,tk,Tcl,Tk,我有一个显示渐变的画布小部件。这是通过从上到下绘制线来完成的,每一条线的颜色略有不同。为了实现这一点,在绘制线条的函数中,我检查画布的高度并根据它绘制线条。问题是,第一次绘制小部件时,或者当小部件调整大小时(调整大小后,我调用绘图函数),我从命令winfo height$legendCanvas得到的结果是错误的,绘图是不好的,只有当我再次调用该函数时,它才能得到正确的值,并且绘图结果是好的。我尝试在方法的开头添加updateidletasks,但它不起作用 相关画布称为legendCanvas

我有一个显示渐变的画布小部件。这是通过从上到下绘制线来完成的,每一条线的颜色略有不同。为了实现这一点,在绘制线条的函数中,我检查画布的高度并根据它绘制线条。问题是,第一次绘制小部件时,或者当小部件调整大小时(调整大小后,我调用绘图函数),我从命令
winfo height$legendCanvas
得到的结果是错误的,绘图是不好的,只有当我再次调用该函数时,它才能得到正确的值,并且绘图结果是好的。我尝试在方法的开头添加
updateidletasks
,但它不起作用

相关画布称为
legendCanvas

itcl::body siReportAttackersMatrix::setThreshold {{val ""}} {
    update idletasks

    # some unrelated code here
    # ...

    #redraw the legend
    $legendCanvas delete line all
    set range [expr {$maxVal*1.0-$minVal}]
    set step  [expr {$range/[winfo height $legendCanvas]}]

    for {set y 0} {$y < [winfo height $legendCanvas]} {incr y} {

        # some unrelated code that calculated the color

        set id [$legendCanvas create line 0 $y [winfo width $legendCanvas] $y -fill $color]

    }
    set textX [expr {[winfo width $legendCanvas]/2}]
    set id [$legendCanvas create text $textX 0 -anchor n -text [expr {int($maxVal * 1000)}]]
    set id [$legendCanvas create text $textX [winfo height $legendCanvas] -anchor s -text [expr {int($minVal * 1000)}]]
    foreach fraction [list 2 4 [expr {4/3.0}]] {
        set textY [expr {int([winfo height $legendCanvas]*1.0/$fraction)}]
        set textValue [expr {int(($maxVal-$minVal)*(1-1.0/$fraction)*1000)}]
        set id [$legendCanvas create text $textX $textY -anchor center -text $textValue]
    }
}
itcl::body siReportAttackersMatrix::setThreshold{{val”“}{
更新idletasks
#这里有一些无关的代码
# ...
#重画传奇
$legendCanvas删除所有行
设置范围[expr{$maxVal*1.0-$minVal}]
设置步骤[expr{$range/[winfo height$legendCanvas]}]
对于{set y 0}{$y<[winfo height$legendCanvas]}{incr y}{
#计算颜色的一些无关代码
设置id[$legendCanvas创建行0$y[winfo width$legendCanvas]$y-填充$color]
}
set textX[expr{[winfo width$legendCanvas]/2}]
set id[$legendCanvas创建文本$textX 0-anchor n-text[expr{int($maxVal*1000)}]]
set id[$legendCanvas create text$textX[winfo height$legendCanvas]-anchor s-text[expr{int($minVal*1000)}]
foreach分数[list 2 4[expr{4/3.0}]]{
set textY[expr{int([winfo height$legendCanvas]*1.0/$fraction)}]
设置textValue[expr{int($maxVal-$minVal)*(1-1.0/$fraction)*1000)}]
设置id[$legendCanvas创建文本$textX$textY-锚定中心-文本$textValue]
}
}
为了节省空间,我删除了与问题相关的代码,比如计算颜色、该方法执行的更多函数以及画布中不同项目的绑定

结果的屏幕图片:

创建时(左侧),调用方法后(右侧):

在重新调整大小(左侧)时,在调用方法(右侧)后:


解决此问题的最简单方法是,每当画布小部件接收到
事件时,重新计算梯度。特别是,
事件中的
%h
%w
替换告诉您小部件的大小设置,尽管基本的Tk基础设施也将把这些值保存到小部件记录中(其中
winfo height
winfo width
可以检索它们)

类似这样的东西;您可能需要调整绑定 绑定$legendCanvas{doRescale%W%W%h}
建议你有一个程序(或方法)来处理这个问题;需要重新缩放的其他操作(如初始设置代码)可以根据需要调用它。

更新idletasks
有时无法实现您想要的功能。我在这里有一个循环,每次迭代都在画布图像对象上放置一个像素;并希望看到每一个像素被画在飞行。使用了
updateidletasks
,我在循环运行时显示了主窗口,但没有显示任何像素;相反,我得到了一个等待光标。然后给了我解决方案:
update
。(不带idletasks)
# Something like this; you might want to tweak the binding
bind $legendCanvas <Configure> { doRescale %W %w %h }