Variable in Gui anzeigen lassen und diese Verändern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
derfium
User
Beiträge: 8
Registriert: Mittwoch 12. Juni 2013, 18:27

Hey Leute!

Ich habe erst vor kurzer Zeit mit Python angefangen und stehe jetzt vor einem Problem, welches mein Lehrer auch nicht lösen kann.
In der Schule nehmen wir das Thema Python gerade anhand der Unterlagen der Seite "inf-schule.de" durch. Dort wird ein Programm geschrieben, mit dem es möglich sein soll Blackjack zu spielen.

Die Gui wird dabei mithilfe von tkinter erstellt.

Mein Problem ist momentan dies:

Ich habe eine Variable i, welche mir den Einsatz des Spielers anzeigen soll.

Code: Alles auswählen

    def i(self, i):
        self.i = i
Aus dieser Variable erstelle ich ein Attribut self.i. Dieses wollte ich mit dann in der Giu mithilfe eines Labels anzeigen lassen

Code: Alles auswählen

self.labelStapelUeberschrift = Label(master=self.frameKartenstapel, text=self.i)
        self.labelStapelUeberschrift.place(x=40, y=70, width=40, height=40)

Leider bekomme ich in der Gui einfach nur irgendwelche Zahlen angezeit, die überhaupt nichts damit zu tun haben.

Desweiteren habe ich einen Button erstellt, der beim klicken auf self.i, also das Attribut, welches ich aus der Variable i erstellt habe 1 draufrechnen soll.

Code: Alles auswählen

 self.buttonEinsatzZahlen = Button(master=self.frameKartenstapel,
                                                 text="Einsatz zahlen",
                                                 command=self.einsatzZahlen)
        self.buttonEinsatzZahlen.place(x=10, y=205, width=100, height=20)

Code: Alles auswählen

    def einsatzZahlen(self):
        self.i = self.i + 1
Beim klicken dieses Buttons passiert in der Gui aber gar nichts, stattdessen bekomme ich diese Fehlermeldung:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "C:\Users\Marcel\Desktop\21\21.py", line 194, in einsatzZahlen
self.i = self.i + 1
TypeError: unsupported operand type(s) for +: 'method' and 'int'


Ich habe echt keine Ahnung wie ich da weiter machen soll und mein Lehrer kenn sich da auch net aus..
Könnt ihr mir vielleicht helfen?

Danke im Vorraus, derfium
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

derfium hat geschrieben:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "C:\Users\Marcel\Desktop\21\21.py", line 194, in einsatzZahlen
self.i = self.i + 1
TypeError: unsupported operand type(s) for +: 'method' and 'int'
Ich habe echt keine Ahnung wie ich da weiter machen soll und mein Lehrer kenn sich da auch net aus..
Könnt ihr mir vielleicht helfen?
Die Fehlermeldung sagt wir ja schon recht viel. Die Addition zwischen einer Methode und einer ganzen Zahl ist nicht definiert. Da 1 eine Zahl ist bleibt ja nur self.i als Methode übrig.

Jetzt überleg dir mal was du hier tust:
derfium hat geschrieben:

Code: Alles auswählen

    def i(self, i):
        self.i = i
Du definierst eine Methode namens "i". Klingelt es jetzt warum bei deinem Fehler oben auf einmal eine Methode auftaucht?
derfium
User
Beiträge: 8
Registriert: Mittwoch 12. Juni 2013, 18:27

Moment... Ich muss das eigfentlich gar nicht als neue Methode defionieren, sondern kann bei der Methode rinsatzZahlen das + 1 gleich auf die Variable draufrechnen und mir die dann anzeigen lassen, oder?
derfium
User
Beiträge: 8
Registriert: Mittwoch 12. Juni 2013, 18:27

Hey!

Ich habe da jetzt mal n bissel weitergemacht und versuche mir jetzt die Variable "i" anzeigen zu lassen.
Am anfang meines GUI-Sriptes setzt ich sie auf 0

Code: Alles auswählen

i = 0
und lasse sie mir dann in einem Label anzeigen:

Code: Alles auswählen

        self.labelStapelUeberschrift = Label(master=self.frameKartenstapel, text=i)
        self.labelStapelUeberschrift.place(x=40, y=70, width=40, height=40)
Den Button habe nich nicht weiter verändert, jedoch den Befehl, den sieser ausführen soll:

Code: Alles auswählen

    def einsatzZahlen(self):
        i = i + 1
        self.anzeigeAktualisieren()
Wenn ich diesen Knopf in meiner GUI betätoige bekomme ich folgende Fehlermeldung:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "C:\Users\Marcel\Desktop\21\21.py", line 194, in einsatzZahlen
i = i + 1
UnboundLocalError: local variable 'i' referenced before assignment
Das verstehe ich löeider nicht so ganz, da ich die Variable ja eigentlich am Anfang definiert habe...

Hab ich da was übersehen, oder ganz falsch gemacht?

Danke im Vorraus :)
BlackJack

@derfium: Das `i` in der Methode ist ein anderes als das „am Anfang des GUI-Skriptes”. Irgendwie habe ich das Gefühl da fehlen Grundlagen die man IMHO drauf haben sollte, bevor man sich mit GUIs beschäftigt.
xeike
User
Beiträge: 83
Registriert: Donnerstag 28. Februar 2013, 09:58

Wenn du in einer Klasse auf eine in der Klasse definierte Variable zugreifen möchtest, dann ist das immer self.i.

Du kannst, musst aber nicht, Funktionen schreiben die "getEinsatz(self)" und "setEinsatz(self, wert)" und "incEinsatz(self)" heissen. Vielleicht macht es das etwas leichter.

Code: Alles auswählen

def getEinsatz(self):
  return self.einsatz

def setEinsatz(self, wert):
  self.einsatz = wert

def incEinsatz(self):
  self.einsatz = self.einsatz + 1
Und dann anschließend:

Code: Alles auswählen

self.labelStapelUeberschrift = Label(master=self.frameKartenstapel, text=getEinsatz())
Alles ungetestet.




Xe
BlackJack

Bitte keine trivialen Getter und Setter. Das ist Java und kein Python.
derfium
User
Beiträge: 8
Registriert: Mittwoch 12. Juni 2013, 18:27

BlackJack hat geschrieben: Irgendwie habe ich das Gefühl da fehlen Grundlagen die man IMHO drauf haben sollte, bevor man sich mit GUIs beschäftigt.
Das sehe ich und der gesamte Kurs, im gegensatz zu unserem Lehrer auch so..
xeike hat geschrieben:Wenn du in einer Klasse auf eine in der Klasse definierte Variable zugreifen möchtest, dann ist das immer self.i.
Aber ich habe die Variable doch nicht in der Klasse definiert...?
xeike hat geschrieben: Du kannst, musst aber nicht, Funktionen schreiben die "getEinsatz(self)" und "setEinsatz(self, wert)" und "incEinsatz(self)" heissen. Vielleicht macht es das etwas leichter.

Code: Alles auswählen

def getEinsatz(self):
  return self.einsatz

def setEinsatz(self, wert):
  self.einsatz = wert

def incEinsatz(self):
  self.einsatz = self.einsatz + 1
Und dann anschließend:

Code: Alles auswählen

self.labelStapelUeberschrift = Label(master=self.frameKartenstapel, text=getEinsatz())
Alles ungetestet.

Xe
Und was ist in dem Fall "wert"? Eine Variable oder ein tatsächlicher Wert?


Danke soweit schonmal!
BlackJack

@derfium: Das ist der Name für das Argument der Methode. Wenn Du die Methode aufrufst, dann natürlich mit einem Wert. Das kann im Quelltext natürlich jeder Ausdruck sein, der zu einem Wert ausgewertet wird, also zum Beispiel auch ein Name an den ein Wert gebunden ist.

Die beiden `get`- und `set`-Methoden solltest Du aber gleich wieder vergessen, denn so triviale Getter und Setter verwendet man in Python nicht. Man greift direkt auf das Attribut zu wenn es Teil der öffentlichen Schnittstelle eines Objekts ist. Getter und Setter machen den Zugriff nur unnötig umständlich ohne einen Mehrwert zu bieten.
derfium
User
Beiträge: 8
Registriert: Mittwoch 12. Juni 2013, 18:27

Ok, dann vergesse ich das mal ganz schnell :D

Zurück zu meinem Problem?

Ich verstehe noch immer nicht warum es bei mir nicht funktioniert... :(

Grüße, derfium
BlackJack

@derfium: Weil der Name `i` in Deiner Methode lokal ist. Das ist ein anderes `i` als das auf Modulebene. Und Du versuchst auf das lokale `i` zuzugreifen bevor ein Wert zugewiesen wurde.
derfium
User
Beiträge: 8
Registriert: Mittwoch 12. Juni 2013, 18:27

Und via self.i kann ich auf die vorher erstellt Varible i zugreifen?
BlackJack

@derfium: Damit kannst Du auf das Attribut `i` auf dem Objekt zu dem die Methode gehört zugreifen.
derfium
User
Beiträge: 8
Registriert: Mittwoch 12. Juni 2013, 18:27

Und wie komm ich dann an die Variable ran?
BlackJack

@derfium: Das ist ein Attribut auf dem Objekt. Also mit dem Punkoperator auf dem Objekt. Innerhalb von Methoden also über den Namen `self` und ausserhalb kommt es halt darauf an wie Du an das Objekt heran kommst. Du solltest echt mal ein Grundlagentutorial durcharbeiten.
derfium
User
Beiträge: 8
Registriert: Mittwoch 12. Juni 2013, 18:27

Hä?!

Naja, ich werde, wenn ich wieder gesund bin, mal mit meinem Lehrer reden, weil wir das nie so wirklich besprochen haben.

Danke soweit schonmal!
Antworten