Seite 1 von 1

Frame durch fremde Klasse packen //bzw.// Fensterwechsel

Verfasst: Freitag 29. August 2008, 16:31
von Janux
Hallo!
Ich möchte, dass im gleichen Fenster nacheinander verschiedene Frames
kommen. (Erst Datei öffnen, dann Lernen, dann Testen)

Ich dachte, dass es gehen würde wenn ich eine Klasse 'Rahmen' mache
und das Layout über eine andere reinpacke.
Wenn der Schritt abgelaufen ist, wollte ich
das mit forget() löschen, und dann in nächsten Schritt wieder ein neues
Layout da rein packen.

Ich hab das Gefühl, dass mein Ansatz schon falsch ist, aber ich
konnte keinen anderen finden. Stecken geblieben bin ich an der Stelle,
wo ich mit der Klasse 'Setup' in der Klasse 'Rahmen' ein Label packen wollte.

Wär kool wenn ihr mir helfen könnt...

Code: Alles auswählen

from Tkinter import *

class Rahmen(Setup):
    def __init__(self):
        Setup.__init__
        self.fenster = Tk()
        self.frame = Frame(self.fenster)
        self.frame.pack()

        self.fenster.minsize(348,243)
        self.fenster.mainloop()

class Setup():
    def __init__(self):
        self.oeffneDatei = Button(self.fenster, text='Datei laden',
                                 command=self.oeffnen)
        self.dateiname = StringVar
        self.anzeige = Label(self.fenster, text=self.dateiname)

        self.oeffneDatei.pack()
        self.anzeige.pack()
                             
    def oeffnen(self):
        pass

#class Lernen:
    pass

programm = Rahmen()

Verfasst: Freitag 29. August 2008, 17:01
von numerix
Das Problem ist nicht, dass deine Grundidee nicht machbar wäre - ob es die RICHTIGE Idee ist, hängt davon ab, wie du es gern hättest, machbar ist es jedenfalls - ,sondern dass dein Code verquer ist.

Dein Programm bildet beim Start eine Instanz von Rahmen, beim Instanziieren wird dann zunächst die __init__()-Methode der Elternklasse aufgerufen, jedenfalls, wenn man es richtig macht. Dann sähe es so aus:

Code: Alles auswählen

Setup.__init__(self)
Die __init__()-Methode von Setup beginnt mit dem Erstellen eines Buttons, dem als master self.fenster übergeben wird - self.fenster gibt es aber noch gar nicht.

Mein Vorschlag: Fang das ganze erst einmal ganz ohne Klassen an. Für so ein bisschen Code braucht es noch keine Klasse und dein Umgang damit zeigt, dass dir das noch nicht so vertraut ist.

Schreib doch erst einmal Code, der den ersten Teil der GUI (also in deinem Fall den ersten Frame) zeigt, wie du ihn gerne hättest. Und dann mal weiter sehen.

Und: Tkinter nicht mit Sternchen importieren. Der Namensraum wird dann überschwemmt und möglicherweise bekommst du irgendwann Probleme mit Kollisionen im Namespace.

Verfasst: Freitag 29. August 2008, 23:43
von Janux
So die GUI funktioniert :)

... nach diesem Prinzip ...

Code: Alles auswählen

from Tkinter import *

class Test:
    def __init__(self):
        self.fenster = Tk()
        self.rahmen = Frame(self.fenster)
        self.rahmen.pack()
        
        self.label1()
        
        self.fenster.mainloop()

    def label1(self):
        self.label = Label(master=self.rahmen, text='Test')
        self.label.pack()
        self.button = Button(master=self.rahmen, text='Weiter',
                             command=self.loeschen)
        self.button.pack()
        

    def loeschen(self):
        self.rahmen.forget()
        self.rahmen2 = Frame(self.fenster)
        self.rahmen2.pack()
        self.label2=Label(self.rahmen2, text='Hallo Welt')
        self.label2.pack()
        self.button2 = Button(self.rahmen2, text='Nochmal',
                             command=self.loeschen2)
        self.button2.pack()

    def loeschen2(self):
        self.rahmen2.forget()
        self.label=Label(self.fenster, text='sdkjfsdj')
        self.label.pack()

f = Test()

Wie man aus fremden Klassen in ein Fenster schreiben kann
würde mich aber trotzdem noch sehr interessieren!

Verfasst: Samstag 30. August 2008, 05:39
von numerix
Janux hat geschrieben:Wie man aus fremden Klassen in ein Fenster schreiben kann
würde mich aber trotzdem noch sehr interessieren!
Ich nehme an, du meinst so etwas:

Code: Alles auswählen

import Tkinter as tk

class A(object):

    def __init__(self):
        self.root = tk.Tk()

    def ready(self):
        self.root.mainloop()

class B(object):

    def setlabel(self):
        tk.Label(a.root, text="Hallo").pack()

a = A()
B().setlabel()
a.ready()
Den Sternchenimport solltest du noch abstellen und dir evtl. Gedanken über aussagekräftigere Namen für deine Widgets machen.

Verfasst: Sonntag 31. August 2008, 15:21
von Janux
Ja,so habe ich das gemeint. Dank dir!


Mir ist aufgefallen, dass meine Programme auch ohne mainloop()
genau so laufen, wie ich möchte. Wozu brauche ich diese Methode überhaupt?

Verfasst: Sonntag 31. August 2008, 16:49
von BlackJack
Die braucht man, damit die GUI auf den Anwender reagiert. Es kann sein, dass das auf bestimmten Plattformen auch ohne geht, das ist aber nicht die Regel.

Verfasst: Sonntag 31. August 2008, 16:54
von Janux
Alles klar. Danke

Verfasst: Sonntag 31. August 2008, 21:13
von numerix
BlackJack hat geschrieben:Die braucht man, damit die GUI auf den Anwender reagiert. Es kann sein, dass das auf bestimmten Plattformen auch ohne geht, das ist aber nicht die Regel.
Es gilt z.B. für IDLE, weil das selbst eine Tkinter-Anwendung ist.

Verfasst: Montag 1. September 2008, 08:06
von Janux
Funktioniert der mainloop() auch richtig, wenn ich ihn über die
__init__-Methode von einer Klasse aufrufe?