Probleme mit Variablen und tkinter

Fragen zu Tkinter.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo Ihr !!!

ich möchte einen Taschenrechner programmieren und habe eine Variable, die die Tastureingabe als String enthält und später zum Berechnen ausgelesen wird.

Hier ist die Eingabe, die man auf dem EntryFeld sieht bei "drücken" der Tasten:

Code: Alles auswählen

      def eingabeeins(self):
                  
            ausgabe = self.ausgabe.get()
            self.ausgabe.insert(50,"1",)

      def eingabezwei(self):

            ausgabe = self.ausgabe.get()
            self.ausgabe.insert(50,"2")
                  
      def eingabedrei(self):

            ausgabe = self.ausgabe.get()
            self.ausgabe.insert(50,"3")
Bei Betätigung der "-" Taste soll der Inhalt ausgelesen werden und in den String gelesen werden:

Code: Alles auswählen

      def eingabeminus(self):

            self.speicher = self.ausgabe.get() + "-"
            
            self.ausgabe.delete(0,END)
Der Inhalt und das Minuszeichen wird auch in den String gelesen, doch bei neuem Durchlauf wird die Variable self.speicher auf "leer" gesetzt, denn ich musste Ihr ja einen Anfangswert geben und das habe ich so gemacht:

Code: Alles auswählen

class Rechner (Frame):
      
      def __init__(self, master=None):
            self.speicher = ""
die Lösung ist bestimmt sehr einfach, doch ich suche in meinem Buch und auf eurer Seite, doch ich kann einfache keine Antwort finden.


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

Hi kaytec!
kaytec hat geschrieben:

Code: Alles auswählen

      def eingabeeins(self):
                  
            ausgabe = self.ausgabe.get()
            self.ausgabe.insert(50,"1",)
# ...
Was ist das? Ich versteh nicht so ganz was du da machst oder machen willst. Wieso nimmst du nicht einfach ein Entry? Und wenn du das nicht willst, nimmst du "bind". Und wo ist jetzt genau dein Problem?
Gruß, jj
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

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

damit kannst du funktionen bzw. methoden an events binden. Wenn du hier oder anderswo suchst, findest du sicher mehr.
Im ge-packt ist's auch recht gut erklärt.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Ich zeige euch mal den code zum Probieren evt. versteht ihr mein Problem!

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-
from Tkinter import *


class Rechner (Frame):
      
      def __init__(self, master=None):
            self.speicher = ""
            
            Frame.__init__(self, master,)
            self.pack()
            self.createWidgets()

      def createWidgets(self):

            

            self.buttonsieben = Button(self, text="7",width=3, command=self.eingabesieben)
            self.buttonsieben.grid(row=7, column=1,padx=10)
            self.buttonacht = Button(self,text="8",width=3, command=self.eingabeacht)
            self.buttonacht.grid(row=7, column=2)
            self.buttonneun = Button(self, text="9",width=3, command=self.eingabeneun)
            self.buttonneun.grid(row=7, column=3,padx=10)
            self.buttonneun = Button(self, text="/",width=3, command=self.eingabedivi)
            self.buttonneun.grid(row=7, column=4)
            self.buttonquadrat = Button(self, text="qua",width=3, command=self.eingabequadrat)
            self.buttonquadrat.grid(row=7, column=5,padx=10)

            self.buttonvier = Button(self, text="4",width=3, command=self.eingabevier)
            self.buttonvier.grid(row=8, column=1,pady=10)
            self.buttonfuenf = Button(self, text="5",width=3, command=self.eingabefuenf)
            self.buttonfuenf.grid(row=8, column=2)
            self.buttonsechs = Button(self, text="6",width=3, command=self.eingabesechs)
            self.buttonsechs.grid(row=8, column=3,)
            self.buttonmulti = Button(self, text="X",width=3, command=self.eingabemulti)
            self.buttonmulti.grid(row=8, column=4)
            self.buttonprozent = Button(self, text="%",width=3, command=self.eingabeprozent)
            self.buttonprozent.grid(row=8, column=5,)

            self.buttoneins = Button(self, text="1",width=3, command=self.eingabeeins)
            self.buttoneins.grid(row=9, column=1)
            self.buttonzwei = Button(self, text="2",width=3, command=self.eingabezwei)
            self.buttonzwei.grid(row=9, column=2)
            self.buttondrei = Button(self, text="3",width=3, command=self.eingabedrei)
            self.buttondrei.grid(row=9, column=3)
            self.buttonminus = Button(self, text="-",width=3, command=self.eingabeminus)
            self.buttonminus.grid(row=9, column=4)
            self.buttonwurzel = Button(self, text="Wu",width=3, command=self.eingabewurzel)
            self.buttonwurzel.grid(row=9, column=5)

            self.buttonnull = Button(self, text="0",width=3, command=self.eingabenull)
            self.buttonnull.grid(row=10, column=1,pady=10)
            self.buttonplusminus = Button(self, text="+/-",width=3, command=self.eingabevorzeichen)
            self.buttonplusminus.grid(row=10, column=2,)
            self.buttonkomma = Button(self, text=",",width=3, command=self.eingabekomma)
            self.buttonkomma.grid(row=10, column=3)
            self.buttonplus = Button(self, text="+",width=3, command=self.eingabeplus)
            self.buttonplus.grid(row=10, column=4)
            self.buttongleich = Button(self, text="=",width=3, command=self.eingabegleich)
            self.buttongleich.grid(row=10, column=5)

      
            self.labelframe=Frame(self)
            self.labelframe.grid(row=0,column=1,pady=15)
            self.ausgabe = Entry(self,width=29,justify="right",)
            self.ausgabe.grid(row=0, column=0,columnspan=6,)


      def eingabeeins(self):
                  
            ausgabe = self.ausgabe.get()
            self.ausgabe.insert(50,"1",)

      def eingabezwei(self):

            ausgabe = self.ausgabe.get()
            self.ausgabe.insert(50,"2")
                  
      def eingabedrei(self):

            ausgabe = self.ausgabe.get()
            self.ausgabe.insert(50,"3")

      def eingabeminus(self):

            self.speicher = self.ausgabe.get() + "-"
            
            self.ausgabe.delete(0,END)
            print self.speicher
            
      def eingabewurzel(self):
            print "Wu"

      def eingabenull(self):
            print 0

      def eingabevorzeichen(self):
            print "+/-"
            
      def eingabekomma(self):
            print ","
                        
      def eingabeplus(self):
            print "+"

      def eingabegleich(self):
            print "="

      def eingabevier(self):
            print 4

      def eingabefuenf(self):
            print 5

      def eingabesechs(self):
            print 6

      def eingabemulti(self):
            print "x"

      def eingabeprozent(self):
            print "%"

      def eingabegleich(self):
            print "="

      def eingabesieben(self):
            print 7

      def eingabeacht(self):
            print 8

      def eingabeneun(self):
            print 9

      def eingabedivi(self):
            print "/"

      def eingabequadrat(self):
            print "qua"
     
     
           


      
      
root = Tk()
root.title('mudda`s Rechner 1.0')
root.config(cursor='crosshair')
Rechner(root).mainloop()
Die print-Anweisungen sind nur, um die Funktion zu prüfen.
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Code: Alles auswählen

# versuchs mal so oder so ähnlich (ungetestet):
        self.buttons=[]
#...
        for i in range (9):
            b=Button(self,text=str(i+1), command=lambda:self.eingabe(zahl))
            b.grid()
            self.buttons.append(b)
    
    def eingabe(self,zahl):
        ausgabe = self.ausgabe.get()
        self.ausgabe.insert(50,zahl)
Das mit den grid-zahlen krigst du mit ein bisschen Mathe auch hin.
Gruß, jj
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Also so ??!!! Ich soll eine Schleife bilden, die mir die einzelnen Tasten 1-9 in einem Vorgang bildet - ok - habe ich vertsanden - nur das Problem mit der Variable ist irgendwie für mich nicht gelöst !?
BlackJack

Ich verstehe das Problem nicht so ganz. Bzw. was Du da überhaupt machen willst.

Wenn der Rechner Punkt vor Strich-Rechnung berücksichtigen soll, könntest Du zum Beispiel Stacks für bisher eingegebene Zahlen und Operationen verwalten. Oder Du implementierst einen RPN Rechner, das ist viel einfacher.

Vielleicht solltest Du den Taschenrechner erst einmal unabhängig von der GUI implementieren. Dann hast Du vorerst nur eine Front, an der Du Dich herumschlagen musst, und nicht die Logik und die GUI gleichzeitig.
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

kaytec hat geschrieben:nur das Problem mit der Variable ist irgendwie für mich nicht gelöst !?
Das hab ich auch noch nicht verstanden.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

das mit gui ist nicht das Problem (glaube ich mal) mache ich nur zu aufwendig. Die Tkinteroberfläche ist ja da, doch sollte die Speichervariable self.speicher die komplette Einagbe speichern, um sie später auszulesen. Das klappt ja auch, doch gebe ich erneut die Zahlen ( bei mir bis jetzt 1,2,3) ein und möchte dann subtrahieren gebe ich ein "-" String dazu. Das Eingabefeld wird gelöscht und nun könnte ich (bei mir bis jetzt 1,2,3 oder auch andere Kombination eingeben) eine neue Zahl eingeben. Danach sollte die Speichervarable den Inhalt (z.B. :123 -123) haben (bei mir wird sie auf "leer" gesetzt und sie hat den Inhalt 123-) . Würde ich nun das Kommando "=" ausführen sollte eine Berechnung stattfinden. alles klar ?!

danke frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Ich habe das mit der Variable gelöst:

Code: Alles auswählen

def eingabeminus(self):

            set(self.speicher)
            self.speicher = self.speicher + self.ausgabe.get() + "-"
            self.ausgabe.delete(0,END)
BlackJack

Was macht die erste Zeile in der Methode?
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

set(self.speicher)
übergibt den unteren Teil der Variable - Ich habe es in einer Reihe geschrieben und da ging es nicht !?
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Das mit dem Kommando "=" habe ich über eval gelöst - jetzt rechnet er schon ! Doch manchmal macht er noch komische Sachen :-).

Code: Alles auswählen

def eingabegleich(self):
            
            ergebnis = eval (self.speicher + self.ausgabe.get())
            self.ausgabe.delete(0,END)
            self.ausgabe.insert(50,ergebnis)
BlackJack

kaytec hat geschrieben:set(self.speicher)
übergibt den unteren Teil der Variable - Ich habe es in einer Reihe geschrieben und da ging es nicht !?
:?: Also hauptsächlich Frage ich deshalb weil `set()` der Name eines (mittlerweile) eingebauten Datentyps ist und damit diese Zeile sinnlos ist. Hast Du Dir selbst eine `set()`-Funktion definiert?
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Du hast recht set brauche ich gar nicht - nur kann ich nicht sagen warum es vorher nicht funktioniert hat ???? na -egal es geht auch ohne!
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo Ihr !!!

Habe mal weiter gemacht, doch bekomme ich eine große Ungenauigkeit bei der Berechnung. So wie ich das verstanden habe, liegt es am Auslesen der Daten und ich müsste das modul decimal verwenden !? Habe ich noch nicht so hinbekommen, doch zwei Schritte vor und manchmal auch drei zurück !!
Den Tip von schlangenbeschwörer habe ich auch noch nicht eingebaut, da ich bei grid () nicht immer pady bzw. padx angeben kann - oder ?? Diese Angaben summieren sich doch auf und die Tastenabstände würden nicht gleich bleiben ?! Ich hatte die Idee, die Werte in eine Tulpe oder Liste einzutragen und auszulesen - macht das Sinn ?

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-
from Tkinter import *

class Rechner (Frame):
      
      def __init__(self, master=None):
            self.speicher = ""
            self.mspeicher = ""
            Frame.__init__(self, master,)
            self.pack()

           
            self.buttonsieben = Button(self, text="7",width=3, command=self.eingabesieben)
            self.buttonsieben.grid(row=7, column=1,padx=10)
            self.buttonacht = Button(self,text="8",width=3, command=self.eingabeacht)
            self.buttonacht.grid(row=7, column=2)
            self.buttonneun = Button(self, text="9",width=3, command=self.eingabeneun)
            self.buttonneun.grid(row=7, column=3,padx=10)
            self.buttonneun = Button(self, text="/",width=3, command=self.eingabedivi)
            self.buttonneun.grid(row=7, column=4)
            self.buttonloeschen = Button(self, text="C",width=3, command=self.loeschen)
            self.buttonloeschen.grid(row=7, column=5,padx=10)

            self.buttonvier = Button(self, text="4",width=3, command=self.eingabevier)
            self.buttonvier.grid(row=8, column=1,pady=10)
            self.buttonfuenf = Button(self, text="5",width=3, command=self.eingabefuenf)
            self.buttonfuenf.grid(row=8, column=2)
            self.buttonsechs = Button(self, text="6",width=3, command=self.eingabesechs)
            self.buttonsechs.grid(row=8, column=3,)
            self.buttonmulti = Button(self, text="X",width=3, command=self.eingabemulti)
            self.buttonmulti.grid(row=8, column=4)
            self.buttonprozent = Button(self, text="%",width=3, command=self.eingabeprozent)
            self.buttonprozent.grid(row=8, column=5,)

            self.buttoneins = Button(self, text="1",width=3, command=self.eingabeeins)
            self.buttoneins.grid(row=9, column=1)
            self.buttonzwei = Button(self, text="2",width=3, command=self.eingabezwei)
            self.buttonzwei.grid(row=9, column=2)
            self.buttondrei = Button(self, text="3",width=3, command=self.eingabedrei)
            self.buttondrei.grid(row=9, column=3)
            self.buttonminus = Button(self, text="-",width=3, command=self.eingabeminus)
            self.buttonminus.grid(row=9, column=4)
            self.buttonspeicher = Button(self, text="M",width=3, command=self.eingabemspeicher)
            self.buttonspeicher.grid(row=9, column=5)

            self.buttonnull = Button(self, text="0",width=3, command=self.eingabenull)
            self.buttonnull.grid(row=10, column=1,pady=10)
            self.buttonplusminus = Button(self, text="+/-",width=3, command=self.eingabevorzeichen)
            self.buttonplusminus.grid(row=10, column=2,)
            self.buttonkomma = Button(self, text=",",width=3, command=self.eingabekomma)
            self.buttonkomma.grid(row=10, column=3)
            self.buttonplus = Button(self, text="+",width=3, command=self.eingabeplus)
            self.buttonplus.grid(row=10, column=4)
            self.buttongleich = Button(self, text="=",width=3, command=self.eingabegleich)
            self.buttongleich.grid(row=10, column=5)

            self.ausgabe = Entry(self,width=29,justify="right",)
            self.ausgabe.grid(row=0, column=0,columnspan=6,pady=10)


      def eingabeeins(self):
            
            self.ausgabe.insert(50,"1",)

      def eingabezwei(self):
            
            self.ausgabe.insert(50,"2")
                  
      def eingabedrei(self):

            self.ausgabe.insert(50,"3")

      def eingabeminus(self):
      
            self.speicher = self.speicher + self.ausgabe.get() + "-"
            self.ausgabe.delete(0,END)
            
            
      def eingabemspeicher(self):

            if self.ausgabe.get() =="":
                  
                  self.speicher = self.speicher + self.mspeicher
                  
            if self.ausgabe.get() !="":
                  
                  self.mspeicher = self.ausgabe.get()
                  self.ausgabe.delete(0,END)
                  self.ausgabe.insert(50,"")
            
      def eingabenull(self):

            self.ausgabe.insert(50,"0")
            
      def eingabevorzeichen(self):

            self.vorzeichen = str(float (self.ausgabe.get()) * -1)
            self.ausgabe.delete(0,END)
            self.ausgabe.insert(50,self.vorzeichen)

            
      def eingabekomma(self):
      
           self.ausgabe.insert(50,".")
                        
      def eingabeplus(self):

            self.speicher = self.speicher + self.ausgabe.get()+ "+"
            self.ausgabe.delete(0,END)
            
      def eingabevier(self):
            
            self.ausgabe.insert(50,"4")

      def eingabefuenf(self):
            
            self.ausgabe.insert(50,"5")

      def eingabesechs(self):

            self.ausgabe.insert(50,"6")

      def eingabemulti(self):
         
            self.speicher = self.ausgabe.get()+ "*"
            self.ausgabe.delete(0,END)

      def eingabeprozent(self):

            self.speicher = self.ausgabe.get()
            self.speicher = (self.speicher + "/" + "100" + "*")
            self.ausgabe.delete(0,END)

      def eingabegleich(self):
            
            try:
                  
                  self.speicher = str(eval (self.speicher + self.ausgabe.get()))
                  self.ausgabe.delete(0,END)
                  self.ausgabe.insert(50,self.speicher)
                  self.speicher = ""
                  
            except:
                  
                  self.ausgabe.delete(0,END)
                  self.speicher = ""
                  self.ausgabe.insert(50,"E")
     
      def eingabesieben(self):
            
            self.ausgabe.insert(50,"7")

      def eingabeacht(self):
            
            self.ausgabe.insert(50,"8")

      def eingabeneun(self):
            
            self.ausgabe.insert(50,"9")

      def eingabedivi(self):
            
            self.speicher = self.speicher + self.ausgabe.get()+ "/"
            self.ausgabe.delete(0,END)

      def loeschen(self):

            self.ausgabe.delete(0,END)
            self.speicher = ""
            self.mspeicher = ""
     
       
root = Tk()
root.title('mudda`s Rechner 1.0')
root.config(cursor='crosshair')
Rechner(root).mainloop()
gruss frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

So wotte ich es mit einer schleife verkürzen, doch ich habe da so meine Probleme. Die Darstellung funktioniert nur bei insert fügt er immer den letzten Durchlauf der schleife ein - macht ja auch irgendwie Sinn - wie kann ich dieses Problem lösen ? Mit einem Zähler: a=a+1 oder so etwas in der Art ?

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-
from Tkinter import *

class Rechner (Frame):
      
      def __init__(self, master=None):
            tastenlayout = [("7",3,7,1,10,0),("8",3,7,2,0,0),("9",3,7,3,10,0),
                               ("4",3,8,1,0,10),("5",3,8,2,0,0),("6",3,8,3,0,0),
                               ("1",3,9,1,0,0),("2",3,9,2,0,0),("3",3,9,3,0,0)]

            Frame.__init__(self, master,)
            self.pack()

            for text, width, row, column, padx, pady in tastenlayout:
                  
                  self.tasten = Button(self, text=text,width=width, command=lambda:self.ausgabe.insert(50,text))
                  self.tasten.grid(row=row, column=column, padx=padx, pady=pady)


                  self.ausgabe = Entry(self,width=29,justify="right",)
                  self.ausgabe.grid(row=0, column=0,columnspan=6,pady=10)


root = Tk()
root.title('mudda`s Rechner 1.0')
root.config(cursor='crosshair')
Rechner(root).mainloop()
gruss frank
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Hi Frank,
Zeile 17 so umändern.

Code: Alles auswählen

self.tasten = Button(self, text=text,width=width,command=lambda self=self, t=text: self.ausgabe.insert(50,t))
dann müsste es gehen.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Danke !!!!

Ja so geht es - nur habe ich es nicht verstanden ?! das self =self konnte ich löschen und es geht trotzdem ? Kann mir das jemand erklären?


gruss und dank frank
Antworten