Seite 1 von 1

Dynamisches ändern des Hauptfensters

Verfasst: Mittwoch 6. Juli 2005, 14:56
von Clython
Hallo Leute

ich hab jetzt ein bisschen mit Tkinter rumgespielt, aber nirgends einen Hinweis gefunden, wie fogendes zu bewerkstelligen ist:

Für mein Programm möchte ich ein Fenster erstellen, dass zuerst einen Text anzeigt, dann auf Knopfdruck (Weiter-Taste) die vorherigen Widegets löscht und durch eine Eingabemaske ersetzt. In diese Eingabemaske schreibt man was rein, dass dann auf aktivierung des Weiter-Knopfes etwas tut und das Resultat im gleichen Fenster anzeigt, vorher aber die Eingabemaske zu löschen. Praktisch wäre auch, wenn man zwischen diesen drei Zuständen mit Weiter und Zurück-Knöpfen hin und herschalten könnte.

Mein Code sieht so aus:

Code: Alles auswählen

import sys
from Tkinter import *
from heatcalc import heat1

def ende():
    sys.exit(0)
    
def weiterzu2():    
    e = Entry(nf)
    e.pack()
    bquad = Button(nf, text = "Quadrieren", command = quad)
    bquad.pack()
    
def weiterzu3():
    lb = Label(hauptfenster, text = "Ergebnis:")
    lb.pack()

def quad():
    eingabe = e.get()
    zahl = float(eingabe)
    lb["text"] = "Ergebnis:" + str(zahl * zahl)

nf = Tk()
fr = Frame(nf, width=200, height=100, relief="sunken", bd=1)
fr.pack(side="top")
nachricht = Label(fr, text = "Whatever")
endebutton = Button(fr, text = "Ende", command = ende)
weiterbutton = Button(fr, text = "Weiter", command = weiterzu2)
nachricht.pack()
endebutton.pack()
weiterbutton.pack()

nf.mainloop()
Ich habe versucht oben genanntes mit einer Quadrier-Funktion zu realisieren, aber dieser Code erzeugt dann einfach die neuen Widgets unterhalb der alten und das Quadrieren funktionert nicht, weil etwas mit get() nicht geht...

Ausserdem ist mir beim nachschauen aufgefallen, dass im Buch Python in a Nutshell anstatt fenster = Tk(), fenster = Tkinter.Tk() aufgerufen wird. Was ist das der Unterschied???

Vielen Dank für die Hilfe

Verfasst: Mittwoch 6. Juli 2005, 16:32
von Clython
Einen Teil habe ich jetzt herausgefunden. Mit

Code: Alles auswählen

irgendeinwidget.pack_forget()
kann man es verschwinden lassen und mit pack() wieder holen, falls nötig. Ich kriege trotzdem noch immer folgende Fehlermeldung, wenn ich die Zahl quadrieren will:

Code: Alles auswählen

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.3/lib-tk/Tkinter.py", line 1345, in __call__
    return self.func(*args)
  File "guiexample.py", line 29, in quad
    eingabe = e.get()
NameError: global name 'e' is not defined
Was mache ich falsch? Sollte doch so eigentlich funktionieren, oder?

Verfasst: Mittwoch 6. Juli 2005, 17:37
von Clython
Ich habs geschafft, aber mich dünkt, der Code ist ein bisschen umständlich, speziell, wenn es mehr als 3 Schritte werden. Gibt es da nicht eine einfachere Art das zu bewerkstelligen?

Code: Alles auswählen

import sys
from Tkinter import *
from heatcalc import heat1
from quad import *

# Definition der Funktionen:

#Standard Funktionen
def ende():
    sys.exit(0)

            
def weiter1():
    def quad():
        eingabe = e.get()
        zahl = float(eingabe)
        e.pack_forget()
        bweiter1.pack_forget()
        lb = Label(froben2, text = "Ergebnis:")
        lb.pack()
        lb["text"] = "Ergebnis:" + str(zahl * zahl)
    bweiter1.config(text = "Quadrieren", command = quad)
    froben.pack_forget()
    froben2 = Frame(mf, width=200, height=100, relief="sunken", bd=1)
    froben2.pack(side="top")
    e = Entry(froben2)
    e.pack()
    
root = Tk()
mf = Frame(root, width=200, height=100, relief="sunken", bd=1)
mf.pack(side="bottom")
frboden = Frame(mf, width=200, height=100, relief="sunken", bd=1)
frboden.pack(side="bottom")
bend = Button(frboden, text ="Ende", command = ende)
bend.pack(side="left")
bweiter1 = Button(frboden, text = "Weiter", command = weiter1)
bweiter1.pack(side="right")

froben = Frame(mf, width=200, height=100, relief="sunken", bd=1)
froben.pack(side="top")
text = Label(froben, text= "Hallo")
#text["height"] = 20
#text["width"] = 20
text.pack()

root.mainloop()

Verfasst: Mittwoch 6. Juli 2005, 18:45
von jAN
sieht doch ganz gut aus
du kannst die pack_forget() auch durch forget() ersetzen hat den selben effekt!
aber warum zerstörst du sie nich gleich?
mit irgendeinwidget.destroy()
und warum importierst du so viele module?
um dir sys zu sparen kannst du auch root.destroy() statt sys.exit(0) verwenden

gruß jAN

Verfasst: Mittwoch 6. Juli 2005, 18:48
von Clython
Danke für die Tipps, aber gibt es keine Möglichkeit, diese Verschachtelungen zu umgehen?

Verfasst: Mittwoch 6. Juli 2005, 19:34
von jAN
vieleicht wenn du nich neue frames erstellst, sondern zb das eingabefeld leerst und dann da das ergebnis reinschreibst
gruß jAN

Verfasst: Mittwoch 6. Juli 2005, 19:50
von jAN
habs hinbekommen:

Code: Alles auswählen

from Tkinter import *

def weiterzu2():  
    entry.pack()
    weiterbutton.config(text = "Quadrieren", command = quad)
def quad():
    quadrat=float(entry.get())**2
    entry.delete(0,'end')
    entry.insert(0,'Ergebnis: '+str(quadrat))

    
root=Tk()
fr = Frame(root, width=200, height=100, relief="sunken", bd=1)
fr.pack(side="top")
nachricht = Label(fr, text = "Whatever")
entry=Entry(nachricht)
endebutton = Button(fr, text = "Ende", command = root.destroy)
weiterbutton = Button(fr, text = "Weiter", command = weiterzu2)
nachricht.pack()
endebutton.pack(side=LEFT)
weiterbutton.pack(side=LEFT)
root.mainloop()
viel spass damit!
gruß jAn

Verfasst: Mittwoch 6. Juli 2005, 20:01
von Clython
Thankee Sai! Ein weiteres Problem gelöst, jetzt muss ich nur noch die ganze Oberfläche schreiben :(

Verfasst: Mittwoch 6. Juli 2005, 20:14
von jAN
naja dann viel spass *gg
kannst mich gerne nochmal fragen in sachen tkinter helf ich gerne