我经常发现自己使用 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
没有after 1000
第 5 行(?)没有错误,也没有效果。如果我尝试 after 10
没有效果。如果我省略 after n
并做update idletasks; $ent xview moveto 1.0
没有效果。
“无效果”表示对话框显示“The Quick Brown Fox Jumps”,字符串的其余部分被隐藏。使用上面的代码,它最初显示,但一秒钟后(正如预期的那样,实际上,如编码的那样)它切换到显示“跳过懒狗”,其余部分隐藏。用户不希望看到未滚动的文本,但除了选择等待的毫秒数之外,我不知道如何避免这种情况。
最佳答案
这是一个非常棘手的问题,比乍一看要复杂得多。问题是,需要处理相当多的空闲事件(这需要不确定但非零的时间)才能充分理解内容以显示数据的结尾,并且此处理发生< em>在您为此类事件绑定(bind)的常用事件之后( <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 用于此目的的内容)。
关于tcl - 在输入框中显示文件名的尾部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17231119/