在输入框中显示文件名的尾部 [英] Display the tail of a filename in an entry box

查看:29
本文介绍了在输入框中显示文件名的尾部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I regularly find myself writing Tk dialog boxes using ttk::entry widgets to prompt for a filename. I save the user's last input to such a dialog and display it as the default when next displaying it.

在我填充小部件后,如果完整的文件名比输入框长,那么它将显示最左边的几个字符,这些字符通常是文件名中不太有趣的部分,我宁愿它显示最右边的字符.

After I've populated the widget, if the full filename is longer than the entry box, then it will display the leftmost few characters which are generally the less interesting part of the filename and I'd rather it displayed the rightmost characters.

我发现立即尝试使用 $entryWidget xview 效果不佳 - 它什么也没做,我认为这是由于某些竞争条件 - 所以我开始编写

I found that attempting to use $entryWidget xview immediately didn't work very well - it did nothing, which I assume was because of some race condition - so I have taken to writing

after $N $entryWidget xview moveto 1.0

有没有更好的方法,如果没有,N 有什么好的选择?我不喜欢有幻数,据我所知,after 0 不能正常工作,after idle 也不能正常工作.

Is there a better way, and if not, what is a good choice for N? I dislike having magic numbers and as far as I recall, after 0 didn't work properly and neither did after idle.

这是一个演示问题的示例

Here's an example demonstrating the problem

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 没有效果.

Without the after 1000 at line 5(?) there is no error, and no effect. If I try after 10 there is no effect. If I leave out the after n and do update idletasks; $ent xview moveto 1.0 there is no effect.

无效果"表示对话框显示The quick brown fox jumps",字符串的其余部分被隐藏.使用上面的代码,它最初显示,但一秒钟后(正如预期的那样,确实如编码),它切换到显示跳过懒狗",其余部分隐藏.用户能够看到未滚动的文本是不可取的,但除了选择一个神奇的毫秒数等待之外,我无法想出如何避免它.

"No effect" means that the dialog box displays "The quick brown fox jumps", the remainder of the string is hidden. With the code as above, it displays that initially but after a second (as expected, indeed, as coded) it switches to display "jumps over the lazy dog" with the rest hidden. It's undesirable for the user to be able to see the unscrolled text, but I can't work out how to avoid it other than by choosing a magic number of milliseconds to wait.

推荐答案

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

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>).

:事实证明,您需要做的是在绘制过程的后期真正推迟对查看位置的调整,到代码> 事件,这是窗口系统要求实际显示在屏幕上的东西的地方.(有一系列复杂的事件经过精心设计以实际将窗口传送到屏幕, 是窗口将出现的通知,code> 是窗口大小更改的通知,而 是实际绘制某些内容的请求.)

: 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

棘手的一点是,我们只想响应 first 事件,而不是每个事件(因为很多都被传递到应用程序的生命周期;在实际执行双缓冲绘图的应用程序实现的底层,还有一个针对此事件的内置处理程序).这意味着我们需要包括取消注册(否则窗口将被钉到最后").

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").

此代码仅适用于第一次显示窗口之前放置的内容.要在此之后移动它,请调用 ttk::entry::See $ent end(这就是 ttk::entry 绑定实现脚本用于此目的).

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).

这篇关于在输入框中显示文件名的尾部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆