2015-12-15 11 views
5

Próbuję nauczyć się jak używać tkintera i znalazłem przydatny kod przez youtube, którego tak naprawdę nie rozumiem w pełni. Byłbym wdzięczny, gdyby niektórzy mogli mi pomóc to zrozumieć. Oznaczono rzeczy nie rozumiałem z **Tkinter! Zrozumienie, jak przełączać ramki

import tkinter as tk # why not from tkinter import? ** 

class SampleApp(tk.Tk): tk.TK** 

    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 

     # the container is where we'll stack a bunch of frames 
     # on top of each other, then the one we want visible 
     # will be raised above the others 

     container = tk.Frame(self) * 
     container.pack(side="top", fill="both", expand=True) 
     container.grid_rowconfigure(0, weight=1) 
     container.grid_columnconfigure(0, weight=1) 

     self.frames = {} 
     for F in (StartPage, PageOne, PageTwo): 
      page_name = F.__name__ 
      frame = F(container, self) ** 
      self.frames[page_name] = frame ** 

      # put all of the pages in the same location; 
      # the one on the top of the stacking order 
      # will be the one that is visible. 
      frame.grid(row=0, column=0, sticky="nsew") 

     self.show_frame("StartPage") 

    def show_frame(self, page_name): 
     '''Show a frame for the given page name''' 
     frame = self.frames[page_name] 
     frame.tkraise() ** 


class StartPage(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) ** 
     self.controller = controller ** 
     label = tk.Label(self, text="This is the start page", 
         font=TITLE_FONT) 
     label.pack(side="top", fill="x", pady=10) 

     button1 = tk.Button(self, text="Go to Page One", 
          command=lambda: controller.show_frame("PageOne")) 
     button2 = tk.Button(self, text="Go to Page Two", 
          command=lambda: controller.show_frame("PageTwo")) 
     button1.pack() 
     button2.pack() 
+0

czy mógłbyś udostępnić link do youtube? –

+0

@BryanOakley W przypadku, gdy wciąż szukałeś, zobaczyłem samouczek [this] (https://www.youtube.com/watch?v=jBUpjijYtCk), który używa Twojego kodu z [pierwotnego pytania] (http: // stackoverflow.com/a/7557028/3826759), chociaż mówi, skąd pochodzi. Jest też [to] (https://pythonprogramming.net/plotting-live-bitcoin-price-data-tkinter-matplotlib/). –

+0

@double_j: tak, znalazłem to jakiś czas temu, ale dzięki. Nie widziałem tego innego linku, który podałeś. Poprawiłem oryginalną odpowiedź, dzięki czemu mogę powiedzieć, kto zaczął od mojego kodu i kto zaczął od tego samouczka wideo. Kod ten przyjął własne życie, pojawia się w wielu pytaniach dla początkujących. –

Odpowiedz

13
import tkinter as tk # why not from tkinter import? ** 

Dlaczego nie from tkinter import *? Ponieważ jest to zły sposób, aby to zrobić. Global imports are bad. Samouczki Tkintera mają tendencję do robienia tego w niewłaściwy sposób z jakiegoś powodu, którego nie rozumiem.

Powód dla części as tk polega na tym, że można wykonać tk.Frame zamiast Tkinter.Frame, dzięki czemu kod jest nieco łatwiejszy do napisania i nieco czytelniejszy. Jest całkowicie opcjonalny.

class SampleApp(tk.Tk): 

tk jest nazwą importowanego modułu tkintera. Tk to nazwa klasy w tym module, która reprezentuje okno główne. Każda aplikacja tkintera musi mieć jedno okno główne. Umieszczenie go wewnątrz SampleApp tworzy podklasę tego widgetu - kopii z dodatkowymi funkcjami.

Nie jest konieczne dziedziczenie z tk.Tk. Możesz dziedziczyć po tk.Frame, dowolnym innym widżecie tkintera lub nawet object. To osobiste preferencje. Wybór sprawia, że ​​niektóre rzeczy są łatwiejsze, a niektóre rzeczy trudniejsze.

container = tk.Frame(self) 

Powyższe stwarza wystąpienie Frame widget, które będą stosowane jako pojemnik dla innych „strony”. Te "strony" będą układane jeden na drugim w tym kontenerze.

frame = F(container, self) 

F to zmienna pętli. Pętla jest iteracją na liście klas, więc za każdym razem poprzez pętlę F będzie reprezentować klasę. F(...) tworzy instancję klasy. Klasy te (StartPage, PageOne, PageTwo) wymagają dwóch parametrów: widżetu będącego rodzicem tej klasy oraz obiektu, który będzie serwerem jako kontroler (termin zapożyczony z modelu/widoku/kontrolera z wzorcem UI )).

Linia kodu tworzy instancję klasy (która sama jest podklasą widżetu Frame) i tymczasowo przypisuje ramkę do lokalnej zmiennej frame.

Podając self jako drugi parametr ("kontroler"), te nowe wystąpienia klas będą mogły wywoływać metody w obiekcie klasy SampleApp.

self.frames[page_name] = frame 

Zapisuje to odniesienie do właśnie utworzonej ramki w słowniku. Kluczem do słownika jest nazwa strony (a dokładniej nazwa klasy).

W ten sposób metoda show_frame może określić rzeczywisty widget strony tylko od nazwy klasy.

frame.tkraise() 

W prawie wszystkich narzędzi GUI - tkinter włączone - istnieje pojęcie „porządku układania”: Kolejność, w której rzeczy są ułożone. Niektóre zestawy narzędzi mogą nazywać to porządkiem z. Jeśli dwa lub więcej widgetów jest ułożonych jeden na drugim (co robi ten kod, umieszczając wszystkie strony w tym samym wierszu i kolumnie), widżet, który znajduje się na szczycie stosu, jest widżetem, który zazwyczaj będzie widoczny.

tkraise to metoda obiektu Frame, która podniesie ramkę do początku kolejności układania. W tym wierszu kodu frame odnosi się do jednej konkretnej instancji jednej ze stron.

tk.Frame.__init__(self, parent) 

Ponieważ każda strona jest podklasą klasy tk.Frame, to wywołuje konstruktor klasy nadrzędnej. Jest to konieczne, aby zainicjować wszystkie wewnętrzne struktury, które składają się na rzeczywisty widget ramki. Chociaż Frame może przyjąć wiele opcji, ten kod wybiera wysyłanie tylko jednego - odniesienia do innego widgetu, który ma pełnić rolę nadrzędnego dla tego nowego widgetu.

self.controller = controller 

Powyższy kod jest po prostu „pamiętanie” wartość controller zmiennej, która została przyjęta w. W tym przypadku, controller jest aplikacja. Po zapisaniu tej klasy można wywoływać metody na obiekcie SampleApp.


Uwaga: kod w pytaniu pochodzi z samouczka, że ​​skopiowany kod z tej odpowiedzi: https://stackoverflow.com/a/7557028/7432. Jestem autorem tego oryginalnego kodu, ale nie autorem samouczka. W tej oryginalnej odpowiedzi znajdują się linki do innych pytań związanych z tym kodem.

+0

dziękuję bardzo! nie wiesz, jak bardzo mi to pomogło! – Baller