2013-06-21 38 views
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 1000在第5行(?)不存在錯誤,並且沒有影響。如果我嘗試after 10則沒有效果。如果我省略after n並執行update idletasks; $ent xview moveto 1.0,則不起作用。

「無效」意味着對話框顯示「快速棕色狐狸跳」,字符串的其餘部分被隱藏。使用上面的代碼,它顯示最初但在一秒鐘後(如預期的那樣,確實如同編碼)它切換顯示「跳過懶狗」,其餘隱藏。用戶能夠看到未滾動的文本是不可取的,但除了選擇等待的毫秒數之外,我無法解決如何避免它。

+0

+1迷人的問題。 「」和「」都不具有約束力。 –

回答

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 ::進入binding implementation scripts使用用於這一目的)。

+0

謝謝Donal。 @Glenn Jackman已經爲此發掘了一份現有的錯誤報告。 – nurdglaw

+0

奇怪。如果我將它複製並粘貼到一個願望殼中,這工作正常,但如果我保存到文件並從一個願望殼中獲取它,它不會。我想這是兩種情況下「相當多」的空閒事件不同的結果。看來我需要回到我的神奇數字。 – nurdglaw

+0

@nurdglaw呃。讓我試試更多... –

1

end是一個有效的index,所以你可以說

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

+0

感謝'moveto end'提示。我關心如何明智地顯示用戶的最後選擇,以及在填充小部件後如何計算'$ entryWidget xview'命令的時間。我會編輯我的問題來澄清。 – nurdglaw

+0

我剛剛嘗試過'xview end',但是它失敗了,錯誤是'expected integer',但得到了'end'。 'xview mmoveto end'失敗,帶有'期望的浮點數,但得到'end''。我在WIndows XP上使用ActiveTcl 8.6.0 – nurdglaw

+0

爲什麼你需要延遲?爲什麼不在設置xview時儘快填充它?這是一個奇怪的錯誤,請顯示您使用的完整命令。 –

相關問題