Seite 2 von 2
Re: Zwei Fenster unabhängig voneinander schließen
Verfasst: Sonntag 26. Juni 2011, 09:30
von Xynon1
Ok, du hast ja Recht, ich war jetzt einfach zu sehr auf Tk fixiert. Obwohl man hier sicher auch nicht-modale-Dialog schreiben kann was aber, wie ich annehme, nicht sehr einfach wird.
Re: Zwei Fenster unabhängig voneinander schließen
Verfasst: Sonntag 26. Juni 2011, 19:54
von problembär
Die Sache ist eigentlich ganz einfach. Folgendes Beispiel (an das von wuf angelehnt, aber ein bißchen mehr an meinen Geschmack angepaßt

):
Code: Alles auswählen
#!/usr/bin/env python
import Tkinter as tk
class MyDialog(tk.Toplevel):
def __init__(self, app_win):
tk.Toplevel.__init__(self)
self.app_win = app_win
self.title("Dialog Window")
self.geometry("+300+250")
self.label = tk.Label(self, text="Please enter something:")
self.label.pack()
self.entry = tk.Entry(self)
self.entry.pack()
self.entry.focus()
self.button_ok = tk.Button(self, text="Ok",
command= self.dialog_end)
self.button_ok.pack()
self.app_win.wait_window(self)
def dialog_end(self):
self.entry_data = self.entry.get()
self.destroy()
class MyTextfield(tk.Toplevel):
def __init__(self, app_win, message):
tk.Toplevel.__init__(self)
self.app_win = app_win
self.message = message
self.tfield = tk.Text(self,
fg = 'black',
bg = 'white')
self.tfield.insert(tk.END, message)
self.button_ok = tk.Button(self, text="Ok",
command= self.textfield_end)
self.button_ok.pack()
self.tfield.pack()
self.app_win.wait_window(self)
def textfield_end(self):
self.destroy()
class MainWin:
def __init__(self):
self.app_win = tk.Tk()
self.app_win.option_add("*font", ("Arial", 15, "normal"))
self.app_win.geometry("+250+200")
self.app_win.title("Example of Custom Dialog-Window")
self.button_dialog = tk.Button(self.app_win,
text="Click button to open dialog-window.",
command = self.create_dialog_and_show_result)
self.button_dialog.pack(padx=20, pady=20)
self.button_exit = tk.Button(self.app_win,
text = "Exit",
command = self.app_win.destroy)
self.button_exit.pack(pady=10)
self.app_win.mainloop()
def create_dialog_and_show_result(self):
self.dialog = MyDialog(self.app_win)
self.textfield = MyTextfield(self.app_win, message = "You entered:\n\n" + self.dialog.entry_data + "\n")
if __name__ == "__main__":
app = MainWin()
So, jetzt kommentiert mal in der Klasse "MyDialog" die Zeile
aus, also ändert sie zu
Jetzt tritt ein Fehler auf. Aha!
Gruß
Re: Zwei Fenster unabhängig voneinander schließen
Verfasst: Sonntag 26. Juni 2011, 20:22
von BlackJack
@problembär: Gibt es irgendeinen bestimmten Punkt auf den Du damit hinaus willst? Dass man die Funktion zum implementieren von modalen Dialogen benutzt, wurde ja nun schon mehrfach gesagt. Das ist aber auch keine magische, unerklärliche Instabilität, sondern schlicht und einfach ein offensichtlicher Logikfehler wenn man den Programmfluss so gestaltet, dass man auf ein Attribut zugreift, welches es noch nicht geben kann, wenn man nicht dafür sorgt, dass der Code der es setzt, *vorher* ausgeführt wird.
Re: Zwei Fenster unabhängig voneinander schließen
Verfasst: Sonntag 26. Juni 2011, 21:25
von wuf
Hallo problembär (The challenger)
Danke für deine Herausforderung. BlackJack hat es schon angedeutet wo das Problem liegt. Habe mir erlaubt etwas von meinem Programmierstil in dein Skript einfliessen zu lassen. Neu wird der Dialog als modales Fenster gezeigt. Das heisst im Hauptfenster sind wärend der Dialog gezeigt wird die Schaltflächen gesperrt und unter Linux sollte der Dialog über dem Hauptfenster zu stehen kommen. Hier das modifizierte Skript:
Code: Alles auswählen
#!/usr/bin/env python
import Tkinter as tk
class MyDialog(tk.Toplevel):
def __init__(self, app_win, callback=None):
self.app_win = app_win
self.callback = callback
tk.Toplevel.__init__(self)
self.title("Dialog Window")
self.geometry("+300+250")
#~~ BEMERKUNG:
# Mache das Toplevel-Fenster Modal
# (Habe dies nur unter Linux getestet)
self.transient(app_win)
self.grab_set()
self.label = tk.Label(self, text="Please enter something:")
self.label.pack()
self.entry = tk.Entry(self)
self.entry.pack()
self.entry.focus()
self.button_ok = tk.Button(self, text="Ok",
command=self.dialog_end)
self.button_ok.pack()
def dialog_end(self):
entry_data = self.entry.get()
self.destroy()
if self.callback != None:
self.callback(entry_data)
class MyTextfield(tk.Toplevel):
def __init__(self, app_win, message):
tk.Toplevel.__init__(self)
self.app_win = app_win
self.message = message
self.tfield = tk.Text(self, fg='black', bg='white')
self.tfield.pack()
self.tfield.insert(tk.END, message)
self.button_ok = tk.Button(self, text="Ok", command=self.textfield_end)
self.button_ok.pack()
def textfield_end(self):
self.destroy()
class MainWin:
def __init__(self):
self.app_win = tk.Tk()
self.app_win.option_add("*font", ("Arial", 15, "normal"))
self.app_win.geometry("+250+200")
self.app_win.title("Example of Custom Dialog-Window")
self.button_dialog = tk.Button(self.app_win,
text="Click button to open dialog-window.",
command = self.create_dialog)
self.button_dialog.pack(padx=20, pady=20)
self.button_exit = tk.Button(self.app_win, text = "Exit",
command = self.app_win.destroy)
self.button_exit.pack(pady=10)
self.app_win.mainloop()
def create_dialog(self):
self.dialog = MyDialog(self.app_win, self.dialog_callback)
def dialog_callback(self, dialog_data):
#print 'Dialog-Callback', dialog_data
self.textfield = MyTextfield(self.app_win,
message="You entered:\n\n" + dialog_data + "\n")
if __name__ == "__main__":
app = MainWin()
Gruß wuf (The opponent)
