Fenster zerstören und neues starten

Fragen zu Tkinter.
Antworten
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Hey,

also ich habe eine Klasse A wo ich ein Fenster A mit gewissen Labels, Entrys und einen Button habe. Ich binde die funktion f() an den Button. Desweiteren existiert eine weitere Klasse B mit einem anderen Fenster B.

Nun möchte ich, wenn der Button gedrückt wird, das Fenster A in der Funktion f() zerstören die Klasse B und damit Fenster B aufrufen.

Mittels destroy kann ich das Fenster A in der Klasse A aber nicht zerstören, da es ja dort noch verwendet wird.

Ungefähr so:

Code: Alles auswählen

class B():
     Label

class A():
    Label
    Entry
    button(command=f)

   def f():
       fenster.destroy()
       b=B()
Wie kann ich das realisieren?
mfg

Thomas :-)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Kennst du die Methode withdraw() für Toplevel-Widgets?
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Ich hab mir das ganze mal angeschaut.

Ich kann mit Toplevel ein neues unabhängiges Fenster generieren (In meinem Fall Fenster B) und über withdraw verstecken.
Jedoch löst das nicht das Problem, dass ich Fenster A nicht in der funktion f zerstören kann.

Zudem kann ich, statt ein Toplevel Fenster zu erstellen auch meine Klasse B aufrufen und somit ein neues Fenster erstellen. Damit ist die Funktion withdraw für mich auch zwecklos.
mfg

Thomas :-)
BlackJack

Bitte mal ein minimales lauffäges Beispiel, dass Dein Problem zeigt, denn ich sehe nicht warum man aus einem Exemplar von `A` das Fenster nicht zerstören können soll.

`Toplevel` ist trotzdem wichtig, weil man in einem Programm keine zwei `Tk`-Exemplare haben kann, ohne massive Probleme zu riskieren. Auch dann nicht, wenn man beide Exemplare "nacheinander" erzeugt, denn wenn das in einer Rückruffunktion eines `Button`\s passiert, gibt es immer einen Zeitpunkt an dem beide "Hauptschleifen" überlappend laufen und damit undefiniertes Programmverhalten provozieren können.
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Code: Alles auswählen

import Tkinter as Tk

class FensterA():
    def __init__(self):
        self.fensterA=Tk.Tk()

        self.button=Tk.Button(master=self.fensterA, text="neues Fenster", command=self.f)
        self.button.pack()

        self.fensterA.mainloop()
        
    def f(self):
        fenster2=FensterB()

class FensterB():
    def __init__(self):
        self.fensterB=Tk.Toplevel()
        self.label=Tk.Label(master=self.fensterB, text="HallO")
        self.label.pack()


fenster1=FensterA()
Ich möchte nun die Klasse FensterB aufrufen und FensterA zerstören, sodass nur noch FensterB sichtbar ist.
Wenn ich jetzt nach Zeile 13 self.FensterA.destroy aufrufen wird FensterA zerstört(keine Ahnung was ich, bevor ich hier gefragt habe falsch gemacht hatte :) ) aber dann wird auch FensterB zerstört.
mfg

Thomas :-)
BlackJack

Tja wie gesagt, 1) es darf nur ein Exemplar von `Tk` geben und 2) wenn man das zerstört, ist das GUI-Programm beendet.
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

//edit: Ich löse das ganze nun über os.startfile und sys.exit. Gefällt mir zwar nicht aber es funktioniert. :lol:
mfg

Thomas :-)
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Du kannst doch, ausgehend vom Root-Window,
beliebieg viele weitere Toplevel-Windows aufmachen,
die sich zerstören oder unsichtbar machen lassen.
Das Root-Window sollte natürlich nicht zerstört werden,
kann aber doch auch unsichtbar gemacht werden.

Das folgende Beispiel erzeugt zunächst ein Root-Window,
auf Button-Click wird dieses unsichtbar und es erscheint
ein weiteres Toplevel-Window.
Der Button in diesem Window löscht das Fenster und es erscheint
wieder das Root-Window.

Code: Alles auswählen

import Tkinter as tk

class A(object):

  def __init__(self):

    self.root = tk.Tk()
    self.but = tk.Button(self.root, text='Hide root', command=self.hide_root)
    self.but.pack()


  def hide_root(self):

    self.topwin = B(self)
    self.root.withdraw()
    #self.root.iconify()


  def show(self):

    self.root.deiconify()


  def run(self):

    self.root.mainloop()


  def fin(self):

    self.root.destroy()

    
class B(object):

  def __init__(self, a):

    self.a = a
    self.top = tk.Toplevel(self.a.root)
    self.tbut = tk.Button(self.top, text='Destroy toplevel',
                          command=self.destroy_b)
    self.top.protocol(name='WM_DELETE_WINDOW', func=self.a.fin)
    self.tbut.pack()
    

  def destroy_b(self):

    self.top.destroy()
    self.a.show()

    
A().run()
Hoffe, es bringt Dich in die richtige Richtung.

:wink:
yipyip
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

ups, hab Dein letztes 'Edit' gar nicht mitbekommen.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

yipyip hat geschrieben:ups, hab Dein letztes 'Edit' gar nicht mitbekommen.
Ist trotzdem gut, dass du gezeigt hast, wie man es *richtig* macht.
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

yipyip danke für das Beispiel. Die Lösung mit startfile hat mir nicht wirklich gefallen aber wie ich es bisher erkennen konnte ist das, was du gepostet hast genau das was ich suche. :)
mfg

Thomas :-)
Antworten