Absoluter Anfänger frage zu mainloop?

Fragen zu Tkinter.
Antworten
thomas223
User
Beiträge: 12
Registriert: Donnerstag 29. Juni 2017, 07:35

Hallo, ich taste mich gerade ein wenig an Tkinker heran. Nun verstehe ich aber diese Mainloop noch nicht.
Das Problem ist, alles vor der Loop wird nur einmal aus geführt und alles danach erst nach beendigen des Fensters.
Nun möchte ich aber gerne eine schleife haben die weiterhin im Kreis läuft, nur wie bekomme ich das hin?
hier man mein Teststück. Also Test wird nur ein mal an gezeigt und Test2 nach beendigen, einer von beiden soll aber dauerhaft durch laufen?

Code: Alles auswählen

from Tkinter import *

def show_entry_fields():
   print("First Name: %s\nLast Name: %s" % (e1.get(), e2.get()))

root = Tk()

w = Label(root, text="Hello Tkinter!")
w.pack()

e1 = Entry(root)
e2 = Entry(root)



e1.pack()
e2.pack()

b1 = Button(root, text='Show', command=show_entry_fields)#.pack
b1.pack()

print "test"

root.mainloop()

print "test2"
Zuletzt geändert von Anonymous am Donnerstag 29. Juni 2017, 09:04, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@thomas223: GUIs und Schleifen, die dauerhaft laufen, vertragen sich nicht, denn die Hauptschleife (mainloop) muß laufen, um Benutzereingaben verarbeiten zu können. Daher sind GUI-Programme völlig anders aufgebaut, als "normale" serielle Programme. Um weiter helfen zu können, müßtest Du verraten, was Du eigentlich in der Schleife tun möchtest.
thomas223
User
Beiträge: 12
Registriert: Donnerstag 29. Juni 2017, 07:35

In der schleife soll ein RFID Schreibgerät RC522 nach Tags suchen und wenn er einen Findet ihn beschreiben und kontrolllesen. die GUI soll eine Benutzeroberfläche sein in der man die zu schreibenden Daten eingeben kann.
BlackJack

@thomas223: Falls die API für das Gerät einen Rückruf anbietet wenn die Ereignisse eintreten an denen Du interessiert bist, dann kommst Du eventuell ohne eigene Threads aus. Das wäre dann das `threading`-Modul, oder `concurrent.futures` (muss man in Python 2 extra installieren). Auf jeden Fall brauchst Du die `after()`-Methode auf Tk-Widgets und eventuell eine `Queue.Queue` (`queue.Queue` in Python 3) um zwischen den Threads zu kommunizieren, denn GUI-Rahmenwerke sind in der Regel nicht „threadsicher“, das heisst man darf die GUI nur aus dem Thread manipulieren in dem auch die GUI-Hauptschleife läuft.

Das ist für Anfänger vielleicht alles ein bisschen viel auf einmal. Von objektorientierter Programmierung sieht man in Deinem Beispiel auch nichts — das ist aber Voraussetzung für GUI-Programmierung. Ohne bekommt man kein sauberes Programm hin.
Nummer_42O
User
Beiträge: 4
Registriert: Samstag 21. September 2019, 14:37

BlackJack hat geschrieben: Donnerstag 29. Juni 2017, 09:36 Von objektorientierter Programmierung sieht man in Deinem Beispiel auch nichts — das ist aber Voraussetzung für GUI-Programmierung. Ohne bekommt man kein sauberes Programm hin.
Da muss ich BlackJack beipflichten. Ich arbeite jetzt schon sehr viel und lange mit Tkinter und bis auf einige kleine Tests, etc. habe ich alles objektorientiert gemacht, weil es einfach das beste für solche Applikaitonen ist.

Um die Frage nach der Tk.mainloop-Funktion zu klären: Innerhalb von Python IDLE laufen Tkinter-GUIs auch ohne mainloop. Diese laufen dann sozusagen im Hintergrund mit, während man die Shell normal benutzen kann. Mit mainloop kann man keine Befehle in der Shell ausführen, da die Applikation jetzt 'aktiv mit in der Shell läuft' (Ja, mir rollen sich bei der Erklärung auch die Fußnägel hoch, aber es verdeutlicht, was ich sagen will.). Wenn man das ganze jetzt außerhalb des Python IDLE betrachtet und das Programm z.B. über die Windows Shell ausführt würde das Programm ohne mainloop sofort beendet werden, da scheinbar alle Tasks erfüllt sind. Wenn die mainloop allerdings läuft ist diese sozusagen der Prozess, der das Programm selber am laufen hält.

Falls ich Ihr Problem richtig verstanden habe, hab' ich evtl. eine Lösung ohne 2. Schleife für Sie:

Code: Alles auswählen

from tkinter import Tk,Entry,StringVar,Label

class App(Tk):
    def __init__(self):
        Tk.__init__(self)
        Label(self,text='Text hier eingeben:').pack()
        self.input=StringVar(self,'')
        self.input.trace('w',self.check)
        Entry(self).pack()
    def check(self):
        text=self.input.get()
        #Suche nach Tag und weitere Vorgänge
 
 if __name__=='__main__': App().mainloop()
Antworten