2

我经常发现自己使用 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 1000at line 5(?) 没有错误,也没有效果。如果我尝试after 10没有效果。如果我省略after nand doupdate idletasks; $ent xview moveto 1.0没有效果。

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

4

2 回答 2

1

end是一个有效的索引,所以你可以说

$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。

于 2013-06-21T09:33:21.810 回答
1

这是一个非常棘手的问题,比起初看起来要复杂得多。问题是它需要处理相当多的空闲事件(这需要不确定但非零的时间量)才能充分理解内容以显示数据的结尾,并且此处理发生在之后您为此类事情绑定的常见事件(<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绑定实现脚本用于该目的的)。

于 2013-06-21T10:59:19.553 回答