2012-03-09 60 views
1

如何加入master = Tk()到tkinter.Frame
的子類的__init__ 產生兩個窗口(appapp2)當只有app.mainloop()叫?創建Tk的兩個實例如何使用一個主循環工作?

from tkinter import Frame,Button,Tk 

class Application(Frame): 

    def say_hi(self): 
     print('Hello world?!') 

    def close(self): 
     self.master.destroy() 

    def createWidgets(self): 
     self.quit_b = Button(self, width=12, text='Quit', bg='tan', 
        command=self.close) 
     self.quit_b.grid(row=0, column=0, padx=8, pady=8) 

     self.hello_b = Button(self, width=12, text='Hello', 
        command=self.say_hi) 
     self.hello_b.grid(row=0, column=1, padx=8, pady=8) 

    def __init__(self): 
     master = Tk() # <------------------------ ! see here ! 
     Frame.__init__(self, master) 
     self.grid() 
     self.createWidgets() 


app = Application() 
app.master.title('Hello world!') 

app2 = Application() 
app2.master.title('Hello world! 2') 

app.mainloop() 

回答

2

不能創建該類Tk的兩個實例,這是有點不尋常另一個類的__init__內實例化。你的代碼應該可以工作,但我從來沒有見過這樣做。

您需要在創建任何其他小部件之前創建Tk的實例。由於您的主應用程序是Frame的子類,因此您在初始化Tkinter之前部分創建了Frame的實例,這根本不是應該完成的方式。它可能工作,但行爲是未定義的。

相反,它通常是更好地創建應用程序傳統知識的一個子類:

from Tkinter import tk 
class Application(tk.Tk): 
    ... 

app = Application(...) 
app.mainloop() 

,或者在全球範圍內建立的Tk一個實例,並作爲參數傳遞到其他部件:

from Tkinter import tk 
class Application(tkFrame): 
    ... 
root = tk.Tk() 
myframe = Application(root) 
root.mainloop() 

如果您需要多個窗口,請使用Toplevel類創建其他窗口。

+0

@HonestAbe:因爲您在Application的構造函數中創建了一個'Tk'實例,並創建了兩個'Application'實例,所以您得到了兩個Tkinter實例。沒有理由這樣做,並會產生意想不到的結果(顯然,因爲發生的事情不是你所期望的)。 – 2012-03-09 21:33:55

+0

我清理了一下這個問題,並刪除了我對這個答案的舊評論。你能編輯這個答案來澄清:「你不能創建類Tk的兩個實例...」。你是說'app2'中的'master = Tk()'代替'app'中創建的那個?然後你能解釋爲什麼app.mainloop()適用於兩者嗎?謝謝! – 2012-08-12 18:49:33

+0

@HonestAbe:'mainloop'不會創建任何窗口,它是一個簡單的事件循環。每次調用'Tk()'時,它都會創建一個窗口並初始化tk子系統。這種初始化不適用於一次應用程序的兩次。 – 2012-08-12 19:22:39

相關問題