Tcl 在输入框中显示文件名的尾部

Tcl 在输入框中显示文件名的尾部,tcl,tk,Tcl,Tk,我经常发现自己在编写Tk对话框时使用ttk::entry小部件来提示输入文件名。我将用户最后的输入保存到这样一个对话框中,并在下次显示时将其显示为默认值 填充小部件后,如果完整文件名比输入框长,则它将显示最左边的几个字符,通常是文件名中不太有趣的部分,我希望它显示最右边的字符 我发现尝试立即使用$entryWidget xview并没有很好的效果——它没有起到任何作用,我认为这是因为某种竞争条件——所以我开始写 after $N $entryWidget xview moveto 1.0 有更

我经常发现自己在编写Tk对话框时使用ttk::entry小部件来提示输入文件名。我将用户最后的输入保存到这样一个对话框中,并在下次显示时将其显示为默认值

填充小部件后,如果完整文件名比输入框长,则它将显示最左边的几个字符,通常是文件名中不太有趣的部分,我希望它显示最右边的字符

我发现尝试立即使用
$entryWidget xview
并没有很好的效果——它没有起到任何作用,我认为这是因为某种竞争条件——所以我开始写

after $N $entryWidget xview moveto 1.0
有更好的方法吗?如果没有,N的好选择是什么?我不喜欢有神奇的数字,据我回忆,0之后的
不能正常工作,空闲之后的
也不能正常工作

这里有一个例子来说明这个问题

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行(?)处1000后没有
,则没有错误,也没有影响。如果我在10后尝试
,则没有效果。如果我在n
之后省略了
,并执行
更新idletasks$ent xview移动到1.0
没有效果


“无效”表示对话框显示“快速棕色狐狸跳跃”,字符串的其余部分隐藏。对于上面的代码,它最初会显示,但在一秒钟后(正如预期的那样,事实上,正如编码的那样),它会切换到显示“跳过懒狗”,其余的隐藏起来。用户不希望看到未滚动的文本,但除了选择一个神奇的等待毫秒数之外,我无法解决如何避免它。

end
是有效的,因此您可以说

$entryWidget xview end
根据您的条目小部件是否处于只读或禁用状态,您可以:

bind $entryWidget <FocusOut> {%W xview end}

条目小部件在最后显示1234。

这是一个非常棘手的问题,比最初看起来要复杂得多。问题在于,它需要处理相当多的空闲事件(这需要一段不确定但非零的时间)才能充分理解内容,以显示数据的结尾,并且这种处理发生在您为此类事情绑定的常见事件之后(

[编辑]:事实证明,您需要做的是将对查看位置的调整推迟到绘图过程的后期,推迟到
事件,在该事件中,窗口系统要求在屏幕上实际显示内容。(有一系列复杂的事件经过精心设计,以实际将窗口传递到屏幕上,
是窗口将出现的通知,
是窗口大小更改的通知,
是实际绘制某物的请求。)

set-ent[ttk::entry.ent]
包装$ent-填充两个-展开“是”
$ent插入结尾“敏捷的棕色狐狸跳过懒惰的狗”
绑定$ent{
#重要提示!取消注册此事件处理程序!
绑定%W{}
#在内容上重新定位视图
%W xview[%W索引结束]
}
设置btn[ttk::button.btn-文本“解除”-命令退出]
包装$btn-填充两个-展开“是”
棘手的一点是,我们只想响应第一个
事件,而不是每一个事件(因为在应用程序的生命周期中交付了很多事件;在实际执行双缓冲绘图的应用程序的底层实现中,还有一个内置的事件处理程序)。这意味着我们需要包括取消注册(否则窗口将被“钉到底”)


此代码仅适用于第一次显示窗口之前放入的内容。要在此之后移动它,请调用
ttk::entry::参见$ent end
(这就是ttk::entry用于此目的的内容)。

感谢
moveto end
提示。我关心的是如何明智地显示用户的最后选择,以及如何在填充小部件后计时
$entryWidget xview
命令。我将编辑我的问题以澄清。我刚刚尝试了
xview end
,但失败了,错误为
预期整数,但得到了“end”
<代码>xview MMO结束
失败,出现
预期的浮点数,但得到“结束”
。我在WIndows XP上使用ActiveTcl 8.6.0,为什么需要延迟?为什么不在填充xview后立即设置它?这是一个奇怪的错误,请显示您使用的完整命令。在设置小部件内容和移动xview之间,可能需要调用
update idletasks
。哪个是“奇怪的错误”?经过一点测试,我发现
$ent xview
滚动显示字符串的结尾,但是
$ent xview end
失败并显示错误消息。当然,这无助于解决时间问题。绑定到
似乎都不起作用。谢谢Donal@格伦·杰克曼已经为这个找到了一个现有的bug报告。奇怪。如果我将它复制并粘贴到一个wish shell中,这很好,但是如果我保存到文件并从wish shell中获取它的源代码,它就不起作用了。我想这是两种情况下“相当多”闲置事件的结果。“看来我需要回到我的魔法数字上去了。”努德格罗。“让我再做一点实验……”努德格劳找到了一种方法。(使用发布的代码在OSX上为我工作。)谢谢Donal,这是一种享受。还感谢
ttk::entry::See
提示-我通常在条目旁边有一个浏览按钮,它需要根据
tk_getOpenFile
或类似的结果填充条目。
$ tclsh
% package req Tk
8.5.10
% entry .e
.e
% pack .e
% .e conf -textvar foo
% set foo {qpowieurpoqwyerpiqyweritqywpeityqwpeitrqiweyrioqwter1234}
qpowieurpoqwyerpiqyweritqywpeityqwpeitrqiweyrioqwter1234
% .e xview end
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