2013-06-27 141 views
2

我知道的Tkinter可以在次挫折的鍛鍊,但我難倒調用到的Tkinter/TTK Toplevel小窗口部件/窗口中的「正確」的順序將:將Tkinter Toplevel窗口同時置於窗口和遠程X11中?

  1. 顯示在窗口不要將它畫在偏心的位置,然後移動它。

  2. 正確調整窗口大小。

  3. 使窗口頂層到父窗體,但不是系統模式(即,不頂層到系統上的所有應用程序/窗口)。

  4. (可選)在Windows上創建任務欄按鈕。

這是當前的代碼,我到目前爲止,有爲了簡單起見,去掉了一些不相關的位:

def __init_ui__(self): 
    #// Basic setup. 
    self.wm_overrideredirect(False) 
    self.wm_resizable(False, False) 
    self.configure(relief=FLAT, borderwidth=4) 

    #// <Some extraneous widget-creation here> 

    #// Done! 
    self.update() 
    self.withdraw() 
    self.update_idletasks() 
    self.grid() 
    self.transient(self._parent) 
    self.grab_set() 
    self.form.initial_focus() #// sets initial focus before the window is displayed 
    center(self) #// https://stackoverflow.com/a/10018670 
    self.deiconify() 
    self._parent._parent.wait_window(self) #// Reaches back to the root Tk() obj. 
    # ENDIF 
# END __init_ui__ 

這種形式從我創建了一個自定義類,它包裝了一堆繼承小窗口創建調用,並且該類繼承自object。第二個繼承來自ttk.Toplevel,使它能夠訪問各種self.wm_*調用和其他Tkinter好東西。

這就是說,我確定我的一些函數調用是不需要的。但是這個特定的調用順序似乎大多在Windows 7上運行良好。然而,在X11-over-ssh(對於Windows中的X服務器使用Xming)的情況下,事情變得更加怪異。在這種情況下,如果我將self.update()設置爲self.withdraw()之後,那麼該窗口將在Windows 7上正確居中而不重繪,但在X11上,該窗口在隱藏時被繪製並正確居中,但具有ZERO幾何(僅限於壓縮窗口邊界/裝飾被顯示)。這就像是網格傳播沒有觸發或者如此。

但是其中self.update()現在正確,它在窗口和X11上正確確定了窗口的大小和居中 - 但您可以看到窗口偏離中心創建,然後移動到兩者的中心。

如果我在Windows上使用self.wm_attributes("-toolwindow", 1),那麼窗口會在我看不到它的時候居中,但-toolwindow只適用於Windows系統。對X11和Aqua來說這是一個無效的命令。

我想避免總是調用tk::windowingsystem來確定我的窗口管理器是什麼,並且不得不針對Windows和X11應用不同的黑客手段。而且我無法測試Mac/Aqua(不擁有它,不會購買),所以我只能希望最終的外觀在該平臺上有些功能。另外,如果我在Windows和遠程X11下單擊另一個窗口/應用程序,通過任務欄按鈕單擊主窗體僅顯示主窗體 - 子窗口Toplevel窗口只在您彈出時彈出點擊主窗體中的任何地方。固定:(有點) - 我忘了給self._transient()添加一個參數有點固定,通過指定父。今天早些時候,我沒有通過父母的觀點,因此焦點不對。

那麼,有沒有某種嘗試和真正的瑪姬配方或調用到Ancient Mu祭司得到的Tkinter/TTK頂層窗口大小,中心,並妥善獲得焦點,如果它不是根窗口?使用最小的X11,Motif外觀,順便說一句。

不,我沒有使用PyGTK的,PyQt的,wxPython中,或者一些其他的工具包。這是標準的Tkinter/ttk或bust,因爲這是我在過去幾周學習和編寫包裝函數所花費的。我製作的自動完成組合框是一個可愛的小玩意兒。仍有小幅越野車,但是這是一個話題另一個SO問題...


PS,在Effbot的Tkinter的食譜已關閉。看起來像服務器崩潰。有沒有人偶然鏡像該網站?

回答

2

解決了!必須調整調用一點點的順序:

#// Done! 
self.withdraw() 
self.grid() 
self.transient(self._parent) 
self.grab_set() 
self.form.initial_focus() 
center(self) 
self.deiconify() 
self._parent._parent.wait_window(self) 

但真正的修復是在center()功能我從this answer提升,通過改變調用winfo_width()/winfo_height()winfo_reqwidth()/winfo_reqheight()並加入到呼叫作爲center()中的第一個呼叫update()。現在,我的對話窗口在中間彈出而不會看到它們移動,焦點正確應用,並且可以在Windows和遠程X11上運行。也許有一天,我會發現它在Mac OS X/Aqua上的運行效果如何。

+0

如果'self'是'Tk'或'Toplevel',然後'self.grid()的實例的引用'是完全無用的。 –

+0

是的,「自己」的父母之一是「Toplevel」,所以可能不需要。 'Toplevel'小部件看上去有些笨拙,尤其是因爲大多數Tkinter/ttk示例都是從'Frame'繼承下來的。 – Kumba

+0

那麼,如果'self'不是最頂層的,那麼它或多或少都可以,但我認爲將一個小部件放入其父項是一種不好的做法。我不明白伏都教的評論 - 除了頂級窗戶,除了Toplevel之外,沒有什麼不可思議的或特殊的。但是,如果'self'不是最頂層,調用'transient'和'deiconify'是沒有意義的 - 該屬性只適用於頂級窗口。您只需將與頂層窗口(撤消,取消等等)相關的命令與僅與不是頂層窗口(網格)的窗口相關的命令混合在一起。 –