我经常发现自己使用ttk :: entry小部件编写Tk对话框来提示输入文件名。我将用户的最后一个输入保存到这样的对话框,并在下次显示时将其显示为默认值。
在我填充小部件之后,如果完整文件名长于输入框,那么它将显示最左边的几个字符,这些字符通常是文件名中不太有趣的部分,我宁愿显示最右边的字符
我发现尝试立即使用$entryWidget xview
并不能很好地工作 - 它没有做任何事情,我认为这是因为一些竞争条件 - 所以我已经写了
after $N $entryWidget xview moveto 1.0
有没有更好的方法,如果没有,N的好选择是什么?我不喜欢有神奇的数字,据我记忆,after 0
没有正常工作,after idle
也没有。
以下是演示问题的示例
package require Tk
set ent [ttk::entry .ent]
pack $ent -fill both -expand yes
$ent insert end "The quick brown fox jumps over the lazy dog"
after 1000 $ent xview moveto 1.0
set btn [ttk::button .btn -text Dismiss -command exit]
pack $btn -fill both -expand yes
第5行(?)没有after 1000
没有错误,也没有效果。如果我尝试after 10
,则无效。如果我遗漏after n
并执行update idletasks; $ent xview moveto 1.0
则无效。
“无效”意味着对话框显示“快速棕色狐狸跳跃”,字符串的其余部分被隐藏。使用上面的代码,它最初显示,但在一秒钟之后(正如预期的那样,确实如编码),它会切换到显示“跳过懒狗”,其余的隐藏。用户不希望能够看到未滚动的文本,但除了选择等待的魔术毫秒数之外,我无法弄清楚如何避免它。
答案 0 :(得分:1)
end
是有效的index,所以你可以说
$entryWidget xview end
根据您的条目窗口小部件是否处于只读状态或禁用状态,您可以:
bind $entryWidget <FocusOut> {%W xview end}
我很惊讶.ent xview end
会返回错误。这对我有用:
$ tclsh
% package req Tk
8.5.10
% entry .e
.e
% pack .e
% .e conf -textvar foo
% set foo {qpowieurpoqwyerpiqyweritqywpeityqwpeitrqiweyrioqwter1234}
qpowieurpoqwyerpiqyweritqywpeityqwpeitrqiweyrioqwter1234
% .e xview end
条目小部件最后显示1234。
答案 1 :(得分:1)
这是一个非常棘手的问题,远远超过最初看起来的问题。问题在于它需要处理相当多的空闲事件(这需要一个不确定但非零的时间)才能足够理解内容以显示数据结束,并且此处理发生< em>在之后为这类事件绑定的常见事件(<Map>
和<Configure>
)。
[编辑]:事实证明,你需要做的是将调整推迟到绘图过程后期真正的观察位置,到<Expose>
事件所在的地方窗口系统要求实际显示在屏幕上的东西。 (这里有一系列复杂的事件,经过精心设计,可以实际向窗口传递一个窗口,<Map>
是窗口显示的通知,<Configure>
是对更改的通知窗口的大小,以及<Expose>
实际绘制内容的请求。)
set ent [ttk::entry .ent]
pack $ent -fill both -expand yes
$ent insert end "The quick brown fox jumps over the lazy dog"
bind $ent <Expose> {
# IMPORTANT! Unregister this event handler!
bind %W <Expose> {}
# Reposition the view on the content
%W xview [%W index end]
}
set btn [ttk::button .btn -text "Dismiss" -command exit]
pack $btn -fill both -expand yes
棘手的一点是,我们希望仅针对第一个 <Expose>
事件采取行动,而不是每个事件(因为相当多的是在应用程序的生命周期内交付;在实际执行双缓冲绘图的应用程序实现的低级别,还有一个内置的事件处理程序。这意味着我们需要包括取消注册(否则窗口将“钉在最后”)。
此代码仅适用于首次显示窗口之前放置的内容。要在此之后移动它,请调用ttk::entry::See $ent end
(这是ttk :: entry binding implementation scripts用于此目的)。