fenster schliessen und neues erzeugen oder inhalt resetten

Fragen zu Tkinter.
Antworten
dac
User
Beiträge: 7
Registriert: Freitag 1. Juni 2007, 09:25

Montag 29. Oktober 2007, 13:44

huhu, ich arbeite grade an einer gui die ich später in mein programm einfügen möchte.
diese gui soll zwei arbeitsschritte(1 und 3) erledigen:

1. dateipfade einlesen und übergeben
2. anhand der daten aus punkt 1 dateien einlesen (ohne gui)
3. teilweise daten ausgeben und per radiobutton/checkbutton eine auswahl treffen und diese dann wieder übergeben
4. anhand der in punkt 3 getroffenen auswahl müssen berechnungen durchgeführt werden (ohne gui)

ich habe mir gedacht das ich einfach zwei guis erzeuge und diese dann der reihe nach ausführen lasse. allerdings funktioniert in meinem testprogramm alles was nach dem löschen der 1. gui kommt nicht mehr. ich habe den eindruck dass das programm mit dem löschen der 1. gui terminiert. dies wäre in zeile 70 der fall



Code: Alles auswählen

# -*- coding: utf-8 -*-
from Tkinter import *
import os
import string
import sys
from tkFileDialog import * 

class gui:

#erste GUI die angezeigt wird
    def gui_eins(self):

        print "start1"
        global root 
        root =Tk()
        name=Entry(root)
        but_sldwaehlen=Button(root,text="SLD Wählen",command=self.gui_eins_sldsuche)
        slddatei=Label(root, text="SLD Datei:")
        global v
        v = StringVar()
        v.set("")
        sldanzeige=Label(root, textvariable=v)
        but_gui_eins_x3dspeichern=Button(root,text="X3D Speichern",command=self.gui_eins_x3dspeichern)
        x3ddatei=Label(root, text="X3D Datei:")
        global x
        x = StringVar()
        x.set("")
        x3danzeige=Label(root, textvariable=x)
        but_gui_eins_abschluss=Button(root,text="Weiter",command=self.gui_eins_abschluss)

        slddatei.pack()
        sldanzeige.pack()
        but_sldwaehlen.pack()
        x3ddatei.pack()
        x3danzeige.pack()
        but_gui_eins_x3dspeichern.pack()
        but_gui_eins_abschluss.pack()

        root.mainloop()

#auswahl welche sld datei geöffnet werden soll
    def gui_eins_sldsuche(self):
        pwd = os.getcwd() 
        dir = "c:/" 
        mask = [("SLD","*.sld")] 
        global sldfilename
        sldfilename = askopenfilename(initialdir = dir, filetypes = mask) 
        name = string.split(sldfilename, '/') 
        laenge = len(name) 
        name = string.split(name[laenge-1], '.')[0] 
        v.set(sldfilename)

#auswahl wohin die x3d datei gespeichert werden soll
    def gui_eins_x3dspeichern(self):
        pwd = os.getcwd() 
        dir = "c:/" 
        mask = [("X3D","*.x3d")] 
        global x3dfilename
        x3dfilename = asksaveasfilename(initialdir = dir, filetypes = mask) 
        name = string.split(x3dfilename, '/') 
        laenge = len(name) 
        name = string.split(name[laenge-1], '.')[0] 
        x.set(x3dfilename)

#abschluss gui_eins
    def gui_eins_abschluss(self):
        print "ende1" #dummy
        print sldfilename
        print x3dfilename
        root.destroy()
        #hier fehlt die funktion um root.mainloop() abzubrechen und das fester zu schliessen, so das einfach die nächste methode ausgeführt wird
        



#zweite GUI die angezeigt wird
    def gui_zwei(self):
        print "start2"        
        global root
        root =Tk()
        name=Entry(root)
        slddatei=Label(root, text="SLD Datei:")
        x3ddatei=Label(root, text="X3D Datei:")
        but_gui_zwei_abschluss=Button(root,text="Weiter",command=gui_zwei_abschluss)

        slddatei.pack()
        x3ddatei.pack()
        but_gui_zwei_abschluss.pack()

        root.mainloop()

#abschluss gui_zwei
    def gui_zwei_abschluss(self):
        print "ende2" #dummy
        root.destroy()

testgui = gui()
testgui.gui_eins()
testgui.gui_zwei()
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Montag 29. Oktober 2007, 14:29

Uh... :x
Du hast Klassen nicht verstanden! global ist echt schlecht, aber global innerhalb einer Klasse...
Zwei Tk-Fenster mit 2 Mainloops sind auch tötlich. Also, es gibt Toplevels, und es gibt auch Frames. Wenn du alles fürs erste Fenster in ein Frame und alles fürs zweite in ein Frame packst und erst nur das eine und dann nur das andere sichtbarmachst oder das erste dann löschst, hast du eine Möglichkeit.rtfm
dac
User
Beiträge: 7
Registriert: Freitag 1. Juni 2007, 09:25

Montag 29. Oktober 2007, 14:40

joa, das mit dem global war auch eher ne notlösung weil ich grade nicht dahinter gekommen bin wie ich die variablen zugängig machen soll. arbeite ich aber noch dran :D

hm, frames...
also wenn ich die theorie aus deinem post richtig verstanden habe kann ich damit mehrere "guis" machen und diese dann der reihe nach "einblenden" ist das korrekt?
wenn ja, cool.
wenn nein, dann korrigiere mich doch bitte.

ich werd mich mal auf die suche nach frames begeben und gucken was ich so rausfinden kann.


danke auf jeden fall
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Montag 29. Oktober 2007, 16:48

Informiere dich doch mal über das mysteriöse "self", das du jeder Methode übergibst, obwohl du garnichts damit machst.
Frames sind hauptsächlich eigentlich zu was anderem gedacht, aber für deine Zwecke sollten sie auch gut arbeiten. Hier mal ein kleines ungetestetes Bsp:

Code: Alles auswählen

import Tkinter as tk
class BeispielGui:
   def __init__(self):
        self.master = tk.Tk()
        self.frame1 = tk.Frame()
        self.frame1.pack()
        tk.Button(self.frame1, text="viel zeug...\n schnell weiter", command=self.nextpage).pack()
        self.frame2 = tk.Frame()
        tk.Label(self.frame2, text="noch mehr zeug...").pack()
   def nextpage(self):
        self.frame1.pack_forget()
        self.frame2.pack()

bsp = BeispielGui()
bsp.master.mainloop()
dac
User
Beiträge: 7
Registriert: Freitag 1. Juni 2007, 09:25

Dienstag 30. Oktober 2007, 10:56

wie self funktioniert weiss ich schon, allerdings änder ich keine programm schnippsel ab damit sie schön aussehen, wenn sie funktionieren und den kompletten code zu posten hatte ich auch nicht unbedingt lust zu.

aber egal...
mit frames mag es funktionieren, allerdings sehr sehr umständlich und auch nicht grad die schönste variante.
ich hab mich dann letzten endes dazu entschlossen ein

Code: Alles auswählen

root.quit()
vor das

Code: Alles auswählen

root.destroy()
zu stellen, somit wird die mainloop beendet bevor das fenster zerstört wird und ich kann so auch ohne probleme im späteren programmverlauf ein neues fenster erzeugen :D
das ist bestimmt nicht die beste lösung, aber sie funktioniert und passt besser zu meinem problem als frames.
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Dienstag 30. Oktober 2007, 11:54

schaumal, warum du keine Klassen und kein self brauchst!
http://paste.pocoo.org/show/8199/
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Dienstag 30. Oktober 2007, 14:34

pyStyler hat geschrieben:schaumal, warum du keine Klassen und kein self brauchst!
Natürlich geht es auch so, aber man muss ja nicht immer mit dem besten Beispiel prahlen...(Tkinter-)GUIs sollte man bei größerem Umfang immer in eine Klasse stecken, allein schon um die Globals etc. nicht zu brauchen.
Sonst musst du nämlich sehr schnell alles global machen, weil du hier auf ein Entry, da auf eine Variable zugreifen musst.
Zwei Tk-Fenster zu erstellen mit 2 Mainloops nacheinander finde ich auch sehr unnormal. Was spricht gegen Frames? Du kannst es ja viel einfacher machen und einfach das letzte Frame zerstören und ein neues nutzen. Das ist in meinen Augen wesentlich sauberer als das Tk-fenster zu zerstören und nen neuen Mainloop zu starten.
Falls du eine Framophobie hast, kannst du auch über ne Schleife einfach alle Child-Widget des Tk-fenster zerstören...
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Dienstag 30. Oktober 2007, 16:21

schlangenbeschwörer hat geschrieben:
pyStyler hat geschrieben:schaumal, warum du keine Klassen und kein self brauchst!
Natürlich geht es auch so, aber man muss ja nicht immer mit dem besten Beispiel prahlen...
verstehe leider nicht wie du das meinst schlangenbeschwörer? Mit dem Code hab ich eher den dac gemeint!
schlangenbeschwörer hat geschrieben:(Tkinter-)GUIs sollte man bei größerem Umfang immer in eine Klasse stecken, allein schon um die Globals etc. nicht zu brauchen.
Da stimme ich dir vollkommen zu.
schlangenbeschwörer hat geschrieben:Sonst musst du nämlich sehr schnell alles global machen, weil du hier auf ein Entry, da auf eine Variable zugreifen musst.
Im Normalfall geht es auch ohne globals
schlangenbeschwörer hat geschrieben:Zwei Tk-Fenster zu erstellen mit 2 Mainloops nacheinander finde ich auch sehr unnormal.
ja, stimmt! Aber das eine mainloop hat mit dem anderen nichts zutun.

Gruss
pyStyler
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Dienstag 30. Oktober 2007, 17:55

pyStyler hat geschrieben:
schlangenbeschwörer hat geschrieben:
pyStyler hat geschrieben:schaumal, warum du keine Klassen und kein self brauchst!
Natürlich geht es auch so, aber man muss ja nicht immer mit dem besten Beispiel prahlen...
verstehe leider nicht wie du das meinst schlangenbeschwörer? Mit dem Code hab ich eher den dac gemeint!
Ja, schon, und ich wollte sagen, dass man einem Anfänger, der Tkinter lernen will, nicht zeigen sollte, wie sein Problem möglichst schlecht gelöst werden kann. Wenn man große GUIs (mit Klassen) bauen möchte, sollte man auch die kleinen in Klassen schreiben, zumindest, bis mans verstanden hat.
Und Hilfestellungen mit "Koplettlösungen" mit "Hauptsache-es-läuft-Code" find ich eher suboptimal. (Mir ist schon klar, das du dac's Code möglichst unverändert lassen wolltest, nur sollte man nicht nur das spezielle Problem lösen, denn sonst hat er morgen das nächste, aufgrund dieses Stiels.)
Antworten