Display the tail of a filename in an entry box

狂风中的少年 提交于 2019-12-06 05:08:53

This is a vastly tricky problem, much more than it appears to be at first. The issue is that it takes the processing of rather a lot of idle events (which take an uncertain but non-zero amount of time) for the content to be comprehended enough for the showing of the end of the data, and this processing happens after the usual events that you bind to for this sort of thing (<Map> and <Configure>).

[EDIT]: It turns out that what you need to do is to postpone the adjustment to the viewing location really late in the drawing process, to the <Expose> event which is where the windowing system asks for things to actually be displayed on the screen. (There's a complex series of events that are choreographed to actually deliver a window to the screen, with <Map> being a notify that the window is to appear, <Configure> being a notify of a change to the size of the window, and <Expose> a request to actually draw something.)

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

The tricky bit is that we want to act in response to just the first <Expose> event, rather than every one (as rather a lot are delivered over the life of an application; there's also a built-in handler for this event at the low level of the implementation of the application that actually does the double-buffered drawing). This means that we need to include a de-registration (otherwise the window will be “nailed to the end”).

This code only works for content placed in before the first time a window is shown. To move it after that, call ttk::entry::See $ent end (which is what the ttk::entry binding implementation scripts use for that purpose).

end is a valid index, so you could say

$entryWidget xview end

Depending if your entry widget is not in readonly or disabled state, you could:

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

I'm surprised .ent xview end returns an error. This works for me:

$ tclsh
% package req Tk
8.5.10
% entry .e
.e
% pack .e
% .e conf -textvar foo
% set foo {qpowieurpoqwyerpiqyweritqywpeityqwpeitrqiweyrioqwter1234}
qpowieurpoqwyerpiqyweritqywpeityqwpeitrqiweyrioqwter1234
% .e xview end

The entry widget displays 1234 at the end.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!