Seite 1 von 1

Fenster zerstören und neues starten

Verfasst: Donnerstag 29. Januar 2009, 19:12
von Python 47
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?

Verfasst: Donnerstag 29. Januar 2009, 19:57
von numerix
Kennst du die Methode withdraw() für Toplevel-Widgets?

Verfasst: Donnerstag 29. Januar 2009, 20:29
von Python 47
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.

Verfasst: Freitag 30. Januar 2009, 02:46
von 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.

Verfasst: Freitag 30. Januar 2009, 14:16
von Python 47

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.

Verfasst: Freitag 30. Januar 2009, 19:34
von 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.

Verfasst: Freitag 30. Januar 2009, 19:37
von Python 47
//edit: Ich löse das ganze nun über os.startfile und sys.exit. Gefällt mir zwar nicht aber es funktioniert. :lol:

Verfasst: Freitag 30. Januar 2009, 20:34
von yipyip
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

Verfasst: Freitag 30. Januar 2009, 20:38
von yipyip
ups, hab Dein letztes 'Edit' gar nicht mitbekommen.

Verfasst: Freitag 30. Januar 2009, 21:35
von numerix
yipyip hat geschrieben:ups, hab Dein letztes 'Edit' gar nicht mitbekommen.
Ist trotzdem gut, dass du gezeigt hast, wie man es *richtig* macht.

Verfasst: Samstag 31. Januar 2009, 11:52
von Python 47
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. :)