dynamische Oberfläche

Fragen zu Tkinter.
Antworten
Benutzeravatar
Windtommyhoff
User
Beiträge: 32
Registriert: Donnerstag 15. März 2007, 13:01
Kontaktdaten:

Hallo @ all!

Ich bin erst seit ca 3 Wochen Pythonianer. Mein Problem ist, dass ich ein Programm erstellen muß, welches eine dynamische Oberfläche besitzt, will heißen: Ich mache eine Eingabe( per Button, oder so) und daraufhin soll sich das Fenster neu generieren, mit den Möglichkeiten, die jetzt noch möglich sind. Stichwort Ausschlußverfahren!
Beispiel:
Button(text="2 Räder"), Button(text="4 Räder")....
Wenn ich jetzt "4 Räder" wähle, soll das Programm mir schonmal die nächsten Optionen für ein Fahrzeug welches NICHT 4 Räder hat, garnicht mehr anzeigen usw.

Ich hoffe ihr könnt mir helfen. Ich hab hier im Forum schon gesucht, aber zum Verr..... nicht das passende gefunden!
Entschuldigung, wenn ich dann jetzt eine doofe Frage stelle, aber ich komme nicht drauf!

Danke schonmal für jede Antwort!

Windtommyhoff

:edit:

Ich weiß nicht ob das wichtig ist, aber ich progge unter XP und habe Python2.5 installiert.
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Hallo,

ich bin mir nicht sicher, ob ich verstanden habe, was du meinst :?

Ich habe hier mal ein Beispiel, in dem die Optionen in Abhängigkeit der vorherigen Auswahl gesetzt werden.

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-


import Tkinter as tk


class Auswahl:
    
    fahrzeuge = {
                'f1': {'preis': 20000, 'farbe': 'schwarz', 'typ': 'Limousine'},
                'f2': {'preis': 15000, 'farbe': 'schwarz', 'typ': 'Turnier'},
                'f3': {'preis': 18000, 'farbe': 'silber', 'typ': 'Limousine'},
                'f4': {'preis': 15000, 'farbe': 'silber', 'typ': 'Mini'},
                'f5': {'preis': 20000, 'farbe': 'schwarz', 'typ': 'Turnier'},
                'f6': {'preis': 20000, 'farbe': 'silber', 'typ': 'Limousine'}
                }
        
    def __init__(self):
        self.root = tk.Tk()
        self.auswahlframe = tk.LabelFrame(self.root, text='Auswahlfeld')
        self.auswahlframe.pack(fill=tk.X)
        self.anzeigeframe = tk.LabelFrame(self.root, 
                                                text='Treffer in der Auswahl')
        self.anzeigeframe.pack(fill=tk.X)
        self.var_preis = tk.IntVar()
        self.var_farbe = tk.StringVar()
        self.var_typ = tk.StringVar()
        self.labels = list()
        self.optionauswahl = list()
        
        for f in self.fahrzeuge.iterkeys():
            self.optionauswahl.append(f)
        self.buttons = list()
        self.optionen_setzen()
        self.auswahlbuttons()
        self.neu = tk.Button(self.root, text='Neue Auswahl', command=self.neueAuswahl)
        self.neu.pack()
       
        self.root.mainloop()

    def optionen_setzen(self):

        self.preise = list()
        self.farben = list()
        self.typen = list()
        
        for f in self.optionauswahl:
            if self.fahrzeuge[f]['preis'] not in self.preise:
                self.preise.append(self.fahrzeuge[f]['preis'])
            if self.fahrzeuge[f]['farbe'] not in self.farben:
                self.farben.append(self.fahrzeuge[f]['farbe'])
            if self.fahrzeuge[f]['typ'] not in self.typen:
                self.typen.append(self.fahrzeuge[f]['typ'])
            
        
    def auswahlbuttons(self):
       
        plabel = tk.Label(self.auswahlframe, text='Preisauswahl: ')
        plabel.pack(side=tk.LEFT)
        self.buttons.append(plabel)
        self.optionPreis = tk.OptionMenu(self.auswahlframe, self.var_preis, 
                                        command=self.treffer, 
                                        *self.preise)
        self.optionPreis.pack(side=tk.LEFT)
        self.buttons.append(self.optionPreis)
        flabel = tk.Label(self.auswahlframe, text='Farbauswahl: ')
        flabel.pack(side=tk.LEFT)
        self.buttons.append(flabel)
        self.optionFarbe = tk.OptionMenu(self.auswahlframe, self.var_farbe, 
                                        command=self.treffer, 
                                        *self.farben)
        self.optionFarbe.pack(side=tk.LEFT)
        self.buttons.append(self.optionFarbe)
        tlabel = tk.Label(self.auswahlframe, text='Typauswahl: ')
        tlabel.pack(side=tk.LEFT)
        self.buttons.append(tlabel)
        self.optionTyp = tk.OptionMenu(self.auswahlframe, self.var_typ, 
                                        command=self.treffer, 
                                        *self.typen)
        self.optionTyp.pack(side=tk.LEFT)
        self.buttons.append(self.optionTyp)
           

    def treffer(self, event=None):
        tmp = list()
        for f in self.optionauswahl:
            if self.var_preis.get() == 0 \
            or self.fahrzeuge[f]['preis'] == self.var_preis.get():
                tmp.append(f)
        self.optionauswahl = tmp
        print self.optionauswahl
        tmp = list()
        for f in self.optionauswahl:
            if self.var_farbe.get() == '' \
            or self.fahrzeuge[f]['farbe'] == self.var_farbe.get():
                tmp.append(f)
        self.optionauswahl = tmp
        print self.optionauswahl
        tmp = list()
        for f in self.optionauswahl:
            if self.var_typ.get() == '' \
            or self.fahrzeuge[f]['typ'] == self.var_typ.get():
                tmp.append(f)
        self.optionauswahl = tmp
        print self.optionauswahl
        self.optionen_setzen()
        for b in self.buttons:
            b.destroy()
        self.auswahlbuttons()

    def neueAuswahl(self):
        for f in self.fahrzeuge.iterkeys():
            self.optionauswahl.append(f)
        self.optionen_setzen()
        for b in self.buttons:
            b.destroy()
        self.auswahlbuttons()
        self.var_preis.set(0)
        self.var_farbe.set('')
        self.var_typ.set('')

 
if __name__ == '__main__':
    Auswahl()
Vielleicht hilft dir das ja weiter.

Mawilo
Benutzeravatar
Windtommyhoff
User
Beiträge: 32
Registriert: Donnerstag 15. März 2007, 13:01
Kontaktdaten:

Danke schonmal für diesen Vorschlag. ich erkläre erstmal meine Aufgabe und Situation zum besseren Verständnis.

Ich bin im Praktikum und soll für eine "Schienenfahrzeugherstellungsfirma" ein Programm schreiben, welches die Eingabe und Ausgabe der Werte vereinfacht, um dann daraus die Standsicherheit dieser Fahrzeuge berechnet. Die haben die verschiedensten Konstellationen von Fahrzeugen, mit Kran oder Arbeitsbühne, mit Kran und Arbeitsbühne und irgendwelchen Auslegern, mit Abstützung des Fahrzeugs, ohne usw..
Bis jetzt machen die diese Berechnung mit einer Exceltabelle in der halt immer alle Angaben gegeben sind, die THEORETISCH möglich sind. Warum soll aber die Höhe der Last im Arbeitskorb abgefragt werden, wenn garkein Arbeitskorb auf dem Fahrzeug vorgesehen ist.
Ich will also eine Oberfläche erstellen, in der man sagen kann:

Das Fahrzeug hat - 2 Achse (und nicht 4)
- ist ausgestattet mit Abstützungen da und da
- hat einen Kran mit der Armlänge
- und eine Arbeitsbühne

Jetzt soll die Oberfläche immer dynamisch angepasst werden, quasi wie schon oben im Beispiel und am Ende nur noch die Eingabefelder (Entry oder so) anzeigen, die benötigt werden und somit mit den Angaben nur noch das ausrechnen und auch ausgeben, was benötigt wird.
Also soll die Oberfläche Benutzerfreundlich, quasi für DAUs bedienbar sein.

Also sollen auch Entrys nur angezeigt werden, wenn bestimmte Bedingungen gegeben sind...

Für weitere Tipps und vor allem Erklärungen der Denkweise und Entstehungsgeschichte der jeweiligen Lösung wäre ich sehr dankbar!! (Ich erinnere Neupythonianer)

Ich wünsche schonmal ein schönes WE und nen schönen Tag noch.

Danke

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

Hi Windtommyhoff!


1. Überleg dir alle Einstellungsmöglichkeiten die du haben willst, ab besten so, das du die, die sich ersetzen sollen unter einen Punkt schreibst.

2. Überleg dir das Gesammtbild, also die anordnung der einzelnen Einstellungspunkte. Auf der einen Seite hast du die Eigenschaften der Fahrzeuge, daneben die Entrys, etc. zum Eingeben der Werte, wenn du das gleichzeitig machen willst, dh. dass man immer, wenn man was am Fahrzeug ändert, neue Etrys sieht. Sonst hast du halt erst das eine, dann das andere Fenster, sodass man sich eimal entscheiden muss, wobei die erste Variante vmt. schöner ist, sofern du nicht ewig viele Einstelleigenschafften hast.

3. Such diir den passenden Geometrymanager, hier am Besten grid, und bau dir das Fenster mit Frames.

4. Jetzt grid-est du die Anfangswerte in die Frames und bindes jede Änderung des Fahrzeugs an einen Eventhandler, der die Eingabemöglichkeiten entsprechend ändert, bzw. updatet, und dann evtl. manche Entrys, Labels, etc. neu beschriftet, den enthaltenen Text löscht, oder remove()-st bzw. grid()-est.

5. Testen und bei Problemen rumprobieren, sonst halt hier den Code posten und das Problem dazuschreiben.

Gruß, jj
Benutzeravatar
Windtommyhoff
User
Beiträge: 32
Registriert: Donnerstag 15. März 2007, 13:01
Kontaktdaten:

Was lange währt wird endlich gut!

Ich hab jetzt das TEST Programm soweit, dass es so funktioniert, wie ich mir das vorgestellt hab!

Hier mal der Code...

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-
from Tkinter import *
import tkMessageBox
import datetime
import time

class Waerme:
    def __init__(self):
        self.root=Tk()
        self.root.title("Wärme-längen-ausdehnung")

        # Die Rahmen zur schönen Anordnung werden erstellt
        self.rahmenL1 = LabelFrame(self.root, text="Ausgangslänge")
        self.rahmenAlpha = LabelFrame(self.root, text="Material")
        self.rahmenDeltaT = LabelFrame(self.root, text="Temperatur")
        self.hilfsrahmen = Frame(self.rahmenDeltaT)
        self.rahmenDeltaL = LabelFrame(self.root, text="Längenänderung")
        self.rahmenL1.grid(row=0, columnspan=30)
        self.rahmenAlpha.grid(row=1, columnspan=30)
        self.rahmenDeltaT.grid(row=2, columnspan=30)
        self.hilfsrahmen.grid(row=0, columnspan=30)
        self.rahmenDeltaL.grid(row=4)
        
        # L1
        self.eingabeL1 = Entry(self.rahmenL1, width=15)
        self.eingabeL1.grid(column=1)
        self.labelL11 = Label(self.rahmenL1, width=14)
        self.labelL13 = Label(self.rahmenL1, width=7)
        self.labelL11.grid(row=0, column=0)
        self.labelL13.grid(row=0, column=2)
        
        # Die Materialbutton werden erstellt
        self.v=IntVar()
        Radiobutton(self.rahmenAlpha, width=15, text="Stahl", value=0, variable=self.v).grid(row=0, column=0)
        Radiobutton(self.rahmenAlpha, width=15, text="Aluminium",value=1, variable=self.v).grid(row=0,column=1)
        Radiobutton(self.rahmenAlpha, width=15, text="Kupfer",value=2, variable=self.v).grid(row=1, columnspan=2)
        self.v.set(0)
        
        self.vt=IntVar()
        Radiobutton(self.hilfsrahmen, width=15, text="Differenz", value=0, variable=self.vt, command=self.entry_manager).grid(row=0, column=0)
        Radiobutton(self.hilfsrahmen, width=15, text="Umgebung/Teil", value=1, variable=self.vt, command=self.entry_manager).grid(row=0, column=1)
        self.vt.set(0)

        # Die Entrys für die Temperatur werden vorbereitet
        self.eingabeDeltaTD=Entry(self.rahmenDeltaT, width=15)
        self.eingabeDeltaTU=Entry(self.rahmenDeltaT, width=15)
        self.eingabeDeltaTT=Entry(self.rahmenDeltaT, width=15)
        self.labelDeltaTD=Label(self.rahmenDeltaT, text="Differenz:", width=14)
        self.labelDeltaTU=Label(self.rahmenDeltaT, text="Umgebung:", width=14)
        self.labelDeltaTT=Label(self.rahmenDeltaT, text="Teil:", width=14)
        
        # Der Knopf wird erstellt
        self.machet = Button(self.root, text="Berechnen", command=self.berechnen)
        self.machet.grid(row=3, columnspan=30, pady=5)
        
        # DeltaL
        self.ausgabeDeltaL = Entry(self.root, width=15)
        self.labelDeltaL = Label(self.root, text="Längenänderung:")
        self.ausgabeDeltaL.grid(row=4, column=1)
        self.labelDeltaL.grid(row=4, column=0)        

        self.f_in = open("c:/Formeln.txt",'r')       # Auslesen der Formel aus der externen Textdatei
        self.formeln=self.f_in.readlines()
        self.f=self.formeln[3]
        self.formel=self.f[:-1]
        self.f_in.close()
        
        self.entry_manager()
        
        self.root.mainloop()

        
# Die Funktion des Buttons wird definiert
    def berechnen(self):
        if self.v.get() == 0:                                           # Abfrage, welches Material gewählt wurde
            self.Alpha = 1.3e-5
        elif self.v.get() ==1:
            self.Alpha = 2.38e-5
        elif self.v.get() ==2:
            self.Alpha = 1.7e-5
        else:
            self.Alpha = 1
            
        try:                                                            # Kontrolle, ob die Eingaben korrekt sind (Buchstabensuche)
            self.L1=float(self.eingabeL1.get())
        except:
            tkMessageBox.showwarning("falsche Eingabe","In Ihren Eingaben wurde eine falsche Eingabe getätigt!\nBitte Wert korrigieren. (,-->.)")
            self.L1 = 0
        if self.vt.get()==0:
            try:                                                        # Kontrolle, ob die Eingaben korrekt sind (Buchstabensuche)
                self.DeltaT=float(self.eingabeDeltaTD.get())                # wenn die Differenz gewählt ist
            except:
                tkMessageBox.showwarning("falsche T Eingabe","In Ihren Eingaben wurde eine falsche Eingabe getätigt!\nBitte Wert korrigieren. (,-->.)")
                self.DeltaT = 0
        elif self.vt.get()==1:
            try:                                                            # wenn die Differenz erst noch errechnet wird
                self.DeltaT=float(self.eingabeDeltaTT.get())-float(self.eingabeDeltaTU.get())
            except:
                tkMessageBox.showwarning("falsche T Eingabe","In Ihren Eingaben wurde eine falsche Eingabe getätigt!\nBitte Wert korrigieren. (,-->.)")
                self.DeltaT = 0
        self.ergeb=eval(self.formel)                                    # Die eingelesene Formel wird mit den eingegebenen Werten gefüttert und das 
        self.ergebs=str(self.ergeb)                                     # Ergebnis an ergeb übergeben
        self.b=self.ergebs.split('.')
        self.c=int(self.b[1])
        if self.c== 0:
            self.ergeb=int(self.b[0])
        self.ausgabe()
    
    def entry_manager(self):                                            # Die Eingabefelder werden angezeigt, bzw. gelöscht
######################################################################### durch diese Funktion
        if self.vt.get()==0:                                            #
            try:                                                        #
                self.eingabeDeltaTU.grid_remove()                       #
                self.eingabeDeltaTT.grid_remove()                       #
                self.labelDeltaTU.grid_remove()                         #
                self.labelDeltaTT.grid_remove()                         #
            except:                                                     # Wenn "Differenz gewählt ist, dann soll versucht werden die Eingaben
                pass                                                    #    für die Umgebungs und Teiltemperatur weg gemacht werden 
                                                                        # Außerdem wird die Eingabe für die Differenz gesetzt und DeltaT auf den 
            self.eingabeDeltaTD.grid(row=1, column=1)		            #    Wert gesetzt, der im Entry steht
            self.labelDeltaTD.grid(row=1, column=0)                     #
#########################################################################
            
#########################################################################
        elif self.vt.get()==1:                                          #
            try:                                                        #
                self.eingabeDeltaTD.grid_remove()                       #
                self.labelDeltaTD.grid_remove()                         #
            except:                                                     #
                pass                                                    #
                                                                        #
            self.eingabeDeltaTU.grid(row=1, column=1)                   #
            self.eingabeDeltaTT.grid(row=2, column=1)                   #
            self.labelDeltaTU.grid(row=1, column=0)                     #
            self.labelDeltaTT.grid(row=2, column=0)                     # 
            try:                                                        # 
                self.DeltaTU=float(self.eingabeDeltaTU.get())           # Wenn Umgebung/Teil gewählt ist wird andersherum verfahren...
                self.DeltaTT=float(self.eingabeDeltaTT.get())           #
            except:                                                     #
                self.DeltaTU, self.DeltaTT= 0,0                         #
                                                                        #
      #      self.DeltaT = self.DeltaTT - self.DeltaTU                  # Außerdem wird DeltaT als Differenz von Umgebungs- und Teiltemperatur
#########################################################################    definiert
       # return self.DeltaT                          
    
    def ausgabe(self):
        self.ausgabeDeltaL.delete(0,END)                                # Ausgabe des Ergebnisses in das Ausgabefeld
        self.ausgabeDeltaL.insert(0,self.ergeb)
    
        self.f_out = open("c:/log.txt",'r')                             # Kontrolle ob die Datei leer ist oder nicht
        self.f=self.f_out.readlines()
        self.f_out.close()
    
        if self.v.get() == 0:                                           # Bestimmung des Materials zum Ausschreiben in die Textdatei
            self.mat = "Stahl"
        elif self.v.get() == 1:
            self.mat = "Aluminium"
        elif self.v.get() == 2:
            self.mat = "Kupfer"
    
        if len(self.f) == 0:                                            # Wenn leer, dann schreiben
            self.dt=datetime.datetime.fromtimestamp(time.time())
            self.f_out = open("c:/log.txt",'w')
            self.f_out.write(str(self.dt.day)+"."+str(self.dt.month)+"."+str(self.dt.year)+" - "+str(self.dt.hour)+":"+str(self.dt.minute)+":"+str(self.dt.second))
            self.f_out.write("\nAusgangslänge: "+str(self.L1))
            self.f_out.write("\nTemperaturunterschied: "+str(self.DeltaT))
            self.f_out.write("\nMaterial: "+str(self.mat))
            self.f_out.write("\nLängenänderung: "+str(self.ergeb))
            self.f_out.close()
        else:
            self.dt=datetime.datetime.fromtimestamp(time.time())
            self.f_out = open("c:/log.txt",'a')                         # Sonst anhängen
            self.f_out.write("\n\n"+str(self.dt.day)+"."+str(self.dt.month)+"."+str(self.dt.year)+" - "+str(self.dt.hour)+":"+str(self.dt.minute)+":"+str(self.dt.second))
            self.f_out.write("\nAusgangslänge: "+str(self.L1))
            self.f_out.write("\nTemperaturunterschied: "+str(self.DeltaT))
            self.f_out.write("\nMaterial: "+str(self.mat))
            self.f_out.write("\nLängenänderung: "+str(self.ergeb))
            self.f_out.close()

if __name__=='__main__':
    Waerme()
Ich bitte darum, alles mögliche dazu zu sagen, was euch ein/auffällt, damit ich einen möglichst schönen; sauberen Programmierstil entwickle und bekomme. Nu mache ich mich an das eigetnliche Programm und bedanke mich schonmal für jede Hilfe!

mfG

Windtommyhoff
Andy
User
Beiträge: 196
Registriert: Sonntag 1. Januar 2006, 20:12
Wohnort: aus dem hohen Norden....

Hi Windtommyhoff (was f. langer Name :D ) und willkommen im Forum!

Code: Alles auswählen

from Tkinter import *
*-Importe sind zu vermeiden. Hierzu kannst Du über die Suchfunktion ne Menge erfahren. (siehe auch Mawilos Beispiel)
Hier wurde es mir erklärt: http://www.python-forum.de/post-57284.html#57284
Diese werden leider zu Unrecht häufig in Einsteiger-Tutorials verwendet.
Antworten