Dictionary zwischen Fenstern übergeben

Fragen zu Tkinter.
Antworten
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Hallo,

ich habe eine größere Anwendung und möchte aus dieser ein neues Fenster starten. Dem neuen Fenster wird ein Dictionary mitgegeben, in das neue Daten geschrieben werden sollen. In dem Fenster werden dann die Daten eingegeben. Wird das Fenster wieder geschlossen, so soll an die Hauptanwendung das geänderte Dictionary (mit den neuen Daten)zurückgegeben werden.
Leider wird das Dictionary erst zurückgegeben, wenn die Hauptanwendung geschlossen wird. Ich habe dazu ein kleines Beispiel gebastelt:

Beispiel Hauptfenster:

Code: Alles auswählen

# -*- coding: iso-8859-15-*- 

import Tkinter as tk
import eingabefenster as ef

class Hauptfenster:
    def __init__(self):
        self.maindic = dict()
        self.oberflache()
        
    def oberflache(self):
        self.root = tk.Tk()
        self.frame = tk.Frame(self.root)
        self.frame.pack()
        
        self.neu = tk.Button(self.frame, text = 'Eingabe', command = self.eingabe)
        self.neu.pack()
        self.root.mainloop()
        
    def eingabe(self):
        print self.maindic
        ef.Eingabe(self.maindic)
        print self.maindic             # 2. print-Anweisung sollte das Dictionary wiedergeben
        
if __name__ == '__main__':
    Hauptfenster()
Das Eingabefenster wird in einer anderen Datei (im Beispiel eingabefenster.py) gespeichert. Hier das Beispiel für das Eingabefenster:

Code: Alles auswählen

# -*- coding: iso-8859-15-*- 

# Beispiel für die Datei eingabefenster.py

import Tkinter as tk

class Eingabe:
    def __init__(self, maindic):
        self.maindic = maindic
        self.root = tk.Toplevel()
        self.frame = tk.Frame(self.root)
        self.frame.pack()
        
        self.en1 = tk.Entry(self.frame, width = 6)
        self.en1.pack()
        self.en2 = tk.Entry(self.frame, width = 6)
        self.en2.pack()
        
        self.bu1 = tk.Button(self.frame, text = 'Übernehmen', command = self.ubernehmen)
        self.bu1.pack()
        self.bu2 = tk.Button(self.frame, text = 'Beenden', command = self.ende)
        self.bu2.pack()
        
        self.root.mainloop()
        
    def ubernehmen(self):
        self.maindic[self.en1.get()] = self.en2.get()
        
    def ende(self):
        self.root.destroy() 
Erwartet habe ich, dass die zweite print-Anweisung in der Funktion eingabe ausgeführt wird, wenn das Eingabefenster zerstört wird. :?

Wie bekomme ich so etwas gebacken?

Stephan
BlackJack

Du springst in Deiner `Eingabe` nochmal in die `mainloop()`, das ist falsch, es sollte nur eine Hauptschleife geben. Einfach den Aufruf weglassen.

Da der Konstruktor dann sofort zurückkehrt wird die zweite ``print``-Anweisung auch sofort ausgeführt. Dagegen kann man auf dem `Toplevel` die Methoden `grab_set()` und `wait_window()` aufrufen um einen modalen Dialog zu bekommen.
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Hallo BlackJack,

ich habe die zweite mainloop() entfernt. Danach wurde sofort das Dictionary zurückgegeben. Da ich es mit wait_window() nicht hinbekommen habe :oops: , verwende ich wait_variable() und übergebe eine BoolVar :D .

Hier die funktionierende Fassung:

Code: Alles auswählen

# -*- coding: iso-8859-15-*- 

import Tkinter as tk
import eingabefenster as ef

class Hauptfenster:
    def __init__(self):
        self.maindic = dict()
        self.oberflache()
        
    def oberflache(self):
        self.root = tk.Tk()
        self.change = tk.BooleanVar()
        self.change.set(False)
        self.frame = tk.Frame(self.root)
        self.frame.pack()
        
        self.neu = tk.Button(self.frame, text = 'Eingabe', command = self.eingabe)
        self.neu.pack()
        self.root.mainloop()
        
    def eingabe(self):
        print self.maindic
        ef.Eingabe(self.maindic, self.change)
        self.root.wait_variable(self.change)
        print self.maindic
        
if __name__ == '__main__':
    Hauptfenster()
Und hier die zweite Datei:

Code: Alles auswählen

# -*- coding: iso-8859-15-*- 

import Tkinter as tk

class Eingabe:
    def __init__(self, maindic, change):
        self.maindic = maindic
        self.change = change
        self.root = tk.Toplevel()
        self.frame = tk.Frame(self.root)
        self.frame.pack()
        
        self.en1 = tk.Entry(self.frame, width = 6)
        self.en1.pack()
        self.en2 = tk.Entry(self.frame, width = 6)
        self.en2.pack()
        
        self.bu1 = tk.Button(self.frame, text = 'Übernehmen', command = self.ubernehmen)
        self.bu1.pack()
        self.bu2 = tk.Button(self.frame, text = 'Beenden', command = self.ende)
        self.bu2.pack()
        
    def ubernehmen(self):
        self.maindic[self.en1.get()] = self.en2.get()
        
    def ende(self):
        self.change.set(True)
        self.root.destroy()
Vielen Dank
Stephan
Antworten