Python: Tkinter: Warum ist es root.mainloop() und nicht app.mainloop()
Ich bin ein neues Mitglied zu Stack Overflow.
Ich fand diesen thread, aber wurde nicht erlaubt, zu kommentieren oder Fragen zu stellen, so dass ich dachte, ich würde nur darauf verweisen hier: Wie kann ich eine in der interaktiven Liste in Python ' s Tkinter komplett mit Tasten, kann die Bearbeitung dieser Inserate?
from tkinter import *
import os
import easygui as eg
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
# character box
Label(frame, text = "Characters Editor").grid(row = 0, column = 0, rowspan = 1, columnspan = 2)
charbox = Listbox(frame)
for chars in []:
charbox.insert(END, chars)
charbox.grid(row = 1, column = 0, rowspan = 5)
charadd = Button(frame, text = " Add ", command = self.addchar).grid(row = 1, column = 1)
charremove = Button(frame, text = "Remove", command = self.removechar).grid(row = 2, column = 1)
charedit = Button(frame, text = " Edit ", command = self.editchar).grid(row = 3, column = 1)
def addchar(self):
print("not implemented yet")
def removechar(self):
print("not implemented yet")
def editchar(self):
print("not implemented yet")
root = Tk()
root.wm_title("IA Development Kit")
app = App(root)
root.mainloop()
Könnte jemand mir erklären, warum die Letzte Zeile ist root.mainloop()?
Ein Anfänger mit Python, und kommen aus einem hintergrund, der von Verfahrens-orientiert mit keine Objekt-orient-Erfahrung, hätte ich gedacht wäre es gewesen, app.mainloop().
In der Tat app = App(root) , app wird nie wieder verwendet und der rest des Codes! Ich habe Schwierigkeiten zu verstehen, warum root.mainloop() funktioniert immer noch.
App
Klasse mit root
, die __init__
- Funktion ausgeführt, in der die ganzen GUI-Komponenten geladen werden. mainloop
ist eine Methode der Tk
beginnt die Ereignis-Schleife des Fensters. Wir haben daher keine Notwendigkeit zu re-Referenz die class
(obwohl wir technisch tun, innerhalb der class
selbst), weil alles, was wir brauchen, ist getan, wenn wir initialisieren, dass class
.InformationsquelleAutor Nuuk | 2014-03-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin nicht sicher, wenn Sie feststellen, dass diese Antwort befriedigend ist, aber Sie rufen
root.mainloop()
weilroot
ist das Objekt, das diemainloop
Methode. In dem code, den Sie gegeben haben,App
hat keinemainloop
Funktion.In einfacheren Worten, das ist nur, wie tkinter funktioniert-Sie werden immer Ihr Skript durch den Aufruf der
mainloop
Methode des root-Fensters. Wenn diese Methode zurückkehrt, wird Ihr Programm beenden.Lasst uns am Anfang beginnen. Die einfachste, nicht-OO Tkinter-Programm Aussehen wird wie im folgenden Beispiel. Beachten Sie, dass dies ist ein python-2.x Beispiel, und ich glaube nicht, verwenden Sie eine Globale importieren, da ich denke, dass die globalen Importe sind schlecht.
Viele Leute finden, dass eine Reine prozedurale Stil ist nicht ein effektiver Weg, um code zu schreiben, so dass Sie können wählen, dies zu schreiben, in einer Objekt-orientierten Stil. Es ist natürlich, zu glauben, "die app" als ein singleton-Objekt. Es gibt viele Möglichkeiten, dies zu tun-das in Ihrer Frage ist leider nicht einer der klareren Möglichkeiten, es zu tun.
Einen etwas besseren Weg, IMO, wäre die Struktur der code wie folgt:
In diesem Fall
mainloop
wird noch genannt, aber jetzt ist es eine Methode derApp
seitApp
erbt vonTk
. Es ist konzeptionell das gleiche wieroot.mainloop()
da in diesem Fallapp
ist das root-Fenster, obwohl es geht durch einen anderen Namen.So, in beiden Fällen
mainloop
ist eine Methode, die gehört auf die root-Fenster. Und in beiden Fällen, es muss aufgerufen werden, für die GUI, um ordnungsgemäß zu funktionieren.Gibt es eine Dritte Variante, die ist, was der code, den Sie ausgewählt wird. Und bei dieser Variante gibt es mehrere Möglichkeiten, es zu implementieren. Die variation ist Ihre Frage verwendet eine Klasse zu definieren, die die Benutzeroberfläche, aber tut nicht Erben von
Tk
. Das ist völlig in Ordnung, aber Sie müssen noch anrufenmainloop
irgendwann. Da Sie nicht erstellen (oder Erben) einemainloop
- Funktion in der Klasse, die Sie anrufen müssen, die man im Zusammenhang mit der root-Fenster. Die Variationen, die ich spreche, sind, wie und wo die Instanz vonApp
Hinzugefügt wird, um das root-Fenster, und wiemainloop
ist letztlich genannt.Persönlich bevorzuge ich, dass
App
erbt vonFrame
, und pack dir die app außerhalb die definition der app. Die Vorlage, die ich benutze sieht wie folgt aus:In diesem letzten Beispiel
app
undroot
sind zwei völlig unterschiedliche Objekte.app
stellt einen Rahmen, der vorhanden ist innen das root-Fenster. Frames werden Häufig verwendet, diese Art, die als container für die Gruppen von anderen widgets.So, in allen Fällen
mainloop
aufgerufen werden muss. wo es genannt wird, und wie, das hängt ein bisschen auf dem coding-Stil. Einige Leute bevorzugen die Erben von der root-Fenster, einige nicht. In beiden Fällen müssen Sie rufen Sie diemainloop
Funktion des root-Fensters.Und weil app und root sind in der gleichen Instanz, alles verpackt in app ist auch sichtbar in der Wurzel, also in das Ende, die Wurzel.mainloop() zeigt alle widgets, die waren verpackt in app.
in dem letzten Beispiel, app und root sind zwei verschiedenen - Objekte. root-das root-Fenster, in dem alle anderen widgets gehen. Es ist eine Instanz der Klasse Tk und jedes tkinter-Applikation muss genau eine Instanz dieser Klasse. app ist eine Instanz der Klasse App, welche eine Unterklasse von Frame. Ein frame ist in der Regel verwendet als container für andere widgets, in diesem Fall die widgets der app (außer für das root-Fenster). Dieser Rahmen ist verpackt in das root-Fenster. app und root sind zwei völlig verschiedene Dinge. root ist ein container für die app.
Wow, vielen Dank für diese elegante Erklärung. Und das machte den Unterschied. Jetzt weiß ich, Frame-und Tk sind zwei völlig verschiedene Klassen. Alles beginnt, mehr Sinn machen. Ich denke, was als Nächstes für mich ist, zu lernen, Python-Klassen, Unterklassen wie Arbeit, erbschaft, etc. Ich glaube, das ist, wo die Verwirrung entstanden ist. Sehen Sie, wenn ich Sie sah
app = App(root)
ich dachte, das bedeutete, dass app wurde eine Unterklasse von root, und root ist eine Instanz der Klasse Tk. Aber Sie beantwortet meine Frage Recht elegant, und wies auf das eigentliche problem: ich brauche einfach zu lernen-Python-Klassen.InformationsquelleAutor Bryan Oakley
Getestet habe ich die beiden wie Sie sehen:
Geschrieben mit "app". + ".pack()" und man nennt "mainframe." + ".grid()"
Dieses Beispiel funktioniert mit python 2.7. In diesem test auch app. verarbeiten kann "mainloop()"
Das script öffnet 2 Fenster, eines nach dem anderen (wenn Sie in der Nähe der ersten) und das erste programm formatiert ist, hat nicht versucht zu schreiben, die colum=3... Sachen in dem pack () - Klammern.
Ich noch begonnen, die Tkinter also nicht gegen mich kämpfen, nur versuchen.. Hoffe ich konnte helfen deine Frage zu beantworten.
Alles gute, Ingo
InformationsquelleAutor III
Den
App
Objekt ist nur Ihre app-code, und der Grund, den Sie nennenApp(root)
ist, um eine Instanz mit Ihrer Klasse, die hat dann Zugang zu Ihrem root-Fenster.Erhält es diese Referenz in der
__init__
Methode:Sehen Sie die gesamte definition der
App
Objekt (gegeben durch den block Anfang mitclass App:
), und es muss nicht einmal einemainloop
Methode, damit zu beginnen, die Haupt-Tkinter-Schleife, Sie müssen rufen Sie es auf das root-Fenster.In der Beispiel in der Python2-Dokumentation, Sie tun nennen Sie es, wie Sie vermutete, sollte gemacht werden, aber beachten Sie, dass Ihr Beispiel-Klasse, die Unterklassen der Tk-Objekt
Frame
. In deinem Beispiel-codeApp
ist ein old-style Klasse, dass die Erben nicht alles.App(root)
ist nicht "auf eine entsprechende Referenz speichern", sondern tatsächlich erstellen die app. Das einzige, was speichert die Referenz ist, wenn Sie weisen das Ergebnis der Variablenapp
. Also, noch einmal, Sie nicht call zum speichern der Referenz weisen Sie es einer Variablen - zum speichern der Referenz.Ich meinte den Grund, warum Sie rufen Sie
App
mitroot
als parameter, aber ich denke, ich sehe, was du meinst.Sie sind noch immer falsch. Sie nennen es nicht mit root als parameter, um zu speichern eine Referenz. Sie nennen es mit root als parameter, da die App-Klasse erfordert, dass Sie sagen, welche Fenster es ist geschaffen werden.
Ich denke immer noch, wir reden hier aneinander vorbei, aber ich angepasst die Formulierung. Die App-Klasse haben muss, um das Fenster übergeben, so dass Sie können es verwenden, (zu sagen, was Fenster erzeugt werden, und möglicherweise andere Anwendungen, je nach der Funktionalität der app) ist der Punkt, den ich versuche zu machen.
Wie Sie alle sehen können, mein Objekt-orientierte wissen ist noch begrenzt. Mein Verständnis ist
root.mainloop()
ist die Haupt-GUI-Fenster, das angezeigt bekommt. Dannapp = App(root)
ist, wo wir erstellen eine Instanz der App Klasse, aber die app wird nie benutzt, sonst irgendwo im code. Doch mit dem erstellen der Instanz der App-Klasse, alles in derdef __init__(self, master):
app ist plötzlich sichtbar auf der main-GUI-Fenster (root -.mainloop()). Wenn dies der falsche Ort das zu Fragen (weil ich wirklich wissen null-Objekt-orientierte-Programmierung), ich werde glücklich sein, um umgeleitet werden, um andere Diskussionen, die möglicherweise erklären.InformationsquelleAutor Two-Bit Alchemist