Tworzenie podokna w Tkinter za pomocą Toplevel()
To jest "przedruk" jednej z moich wypowiedzi na polskim forum Pythona. http://pl.python.org/forum/index.php?topic=4366.msg18662#msg18662
Złóżone GUI posiada tylko jedno okno główne a wszystko inne to jego potomstwo. Jest to naturalny sposób działania - (prawie) każdy program tak działa (niezależnie od języka czy biblioteki do GUI).
Tak więc dla głównego okna używa się Tk()
a do całej reszty
Toplevel()
.
Można tworzyć te okna poprzez bezpośrednie wywołanie Tk()
,
Toplevel()
wewnątrz klas i przypisanie do zmiennej np.
self.master
aby potem mieć dostęp do właściwości danego okna przez
self.master
(wewnątrz klasy) i nazwa_okna.master
poza klasą.
import Tkinter as tk
#----------------------------------------------------------------------
class Main():
def __init__(self):
self.master = tk.Tk() # bezposrednie tworzenie okna
self.master.title("Main") # wewnetrzny dostep do wlasnosci okna
tk.Button(self.master, text="Otworz okno Child z okna Main", command=self.onButton).grid()
def onButton(self):
self.child = Child(self.master) # przekazanie okna jako rodzica
def run(self):
self.master.mainloop()
#----------------------------------------------------------------------
class Child():
def __init__(self, parent):
self.master = tk.Toplevel(parent) # bezposrednie tworzenie okna
self.master.title("Child") # wewnetrzny dostep do wlasnosci okna
tk.Button(self.master, text="Otworz okno Child z okna Child", command=self.onButton).grid()
def onButton(self):
self.child = Child(self.master) # przekazanie okna jako rodzica
#----------------------------------------------------------------------
glowne = Main()
glowne.master.title("Glowne") # zewnetrzny dostep do wlasnosci okna
glowne.run()
Można też robić to poprzez "dziedziczenie klas" i wtedy cała klasa jest
jakby oknem i do własności okna ma się dostęp przez self
(wewnątrz
klasy) i nazwa_okna
poza klasą.
import Tkinter as tk
#----------------------------------------------------------------------
class Main(tk.Tk): # dziedziczenie po klasie tk.Tk
def __init__(self):
tk.Tk.__init__(self) # wywolanie konstruktora klasy tk.Tk
self.title("Main") # wewnetrzny dostep do wlasnosci okna
tk.Button(self, text="Otworz okno Child z okna Main", command=self.onButton).grid()
def onButton(self):
self.child = Child(self) # przekazanie okna jako rodzica
def run(self):
self.mainloop()
#----------------------------------------------------------------------
class Child(tk.Toplevel): # dziedziczenie po klasie tk.Toplevel
def __init__(self, parent):
tk.Toplevel.__init__(self, parent) # wywolanie konstruktora klasy tk.Toplevel
self.title("Child") # wewnetrzny dostep do wlasnosci okna
tk.Button(self, text="Otworz okno Child z okna Child", command=self.onButton).grid()
def onButton(self):
self.child = Child(self) # przekazanie okna jako rodzica
#----------------------------------------------------------------------
glowne = Main()
glowne.title("Glowne") # zewnetrzny dostep do wlasnosci okna
glowne.run()
Można ewentualnie jeszcze przekazywać z zewnątrz okno do klasy. I wtedy
można decydować, które okno jest nam potrzebne jako główne - trzeba
tylko pamiętać o mainloop()
i albo dodać go też do Child albo użyć
poza klasami.
import Tkinter as tk
#----------------------------------------------------------------------
class Main():
def __init__(self, master):
self.master = master # otrzymanie okna z zewnatrz
self.master.title("Main") # wewnetrzny dostep do wlasnosci okna
tk.Button(self.master, text="Otworz okno Child z okna Main", command=self.onButton).grid()
def onButton(self):
self.child = Child(tk.Toplevel(self.master)) # przekazanie okna
# def run(self):
# self.master.mainloop()
#----------------------------------------------------------------------
class Child():
def __init__(self, master):
self.master = master # otrzymanie okna z zewnatrz
self.master.title("Child") # wewnetrzny dostep do wlasnosci okna
tk.Button(self.master, text="Otworz okno Child z okna Child", command=self.onButton).grid()
def onButton(self):
self.child = Child(tk.Toplevel(self.master)) # przekazanie okna
# def run(self):
# self.master.mainloop()
#----------------------------------------------------------------------
master = tk.Tk()
glowne = Main(master)
master.title("Glowne") # dostep do wlasnosci okna
master.mainloop()
# wykorzystanie dziecka jako okno glowne z pominieciem okna Main()
master = tk.Tk()
glowne = Child(master)
master.title("Glowne Dziecko") # dostep do wlasnosci okna
master.mainloop()
Podział kodu na kilka plików (każda klasa w osobnym pliku) jest jak
najbardziej możliwy.
A za pomoca __name__
będzie można wykorzystywać Child
jako
podokno a także jako samodzielne okno główne
main_only.py
import Tkinter as tk
from child_only import *
#----------------------------------------------------------------------
class Main():
def __init__(self, master):
self.master = master # otrzymanie okna z zewnatrz
self.master.title("Main") # wewnetrzny dostep do wlasnosci okna
tk.Button(self.master, text="Otworz okno Child z okna Main", command=self.onButton).grid()
def onButton(self):
self.child = Child(tk.Toplevel(self.master)) # przekazanie okna
# def run(self):
# self.master.mainloop()
#----------------------------------------------------------------------
if __name__ == '__main__':
master = tk.Tk()
glowne = Main(master)
master.title("Glowne") # dostep do wlasnosci okna
master.mainloop()
child_only.py
import Tkinter as tk
#----------------------------------------------------------------------
class Child():
def __init__(self, master):
self.master = master # otrzymanie okna z zewnatrz
self.master.title("Child") # wewnetrzny dostep do wlasnosci okna
tk.Button(self.master, text="Otworz okno Child z okna Child", command=self.onButton).grid()
def onButton(self):
self.child = Child(tk.Toplevel(self.master)) # przekazanie okna
# def run(self):
# self.master.mainloop()
#----------------------------------------------------------------------
if __name__ == '__main__':
master = tk.Tk()
glowne = Child(master)
master.title("Glowne Dziecko") # dostep do wlasnosci okna
master.mainloop()
Buy a Coffee