Buttonfehler

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
Mr.101Freaking
User
Beiträge: 6
Registriert: Samstag 30. Mai 2015, 14:34

Moin nach einiger Zeit habe ich doch mal wieder eine Frage auf die ich bisher keine Antwort finden konnte :/
aber da es das letzte mal so gut geklappt hat bin ich zuversichtlich das ihr mir hier weiterhelfen könnt
habe den code wieder aus wesentliche runtergebrochen:

Code: Alles auswählen

from tkinter import *
from widget_handler import *

root = Tk()

wndw = Frame(root)
wndw.grid()

gv = str(100) #globale var

def test1(gv):
    v = str(25 + 3)
    gv = v

    print(gv)
    print("---------")
    print(v)
    return(gv)

def test2():
    print(gv)

b1 = Button(wndw, text="tst1", command=test1(gv))
b1.grid(row=0,column=0)

b2 = Button(wndw, text="tst2", command=test2)
b2.grid(row=0,column=1)

root.mainloop()
das problem ist so wie ich das sehe 2geteilt auf der einen seite wird der command zu b1 nur zum programmstart einmal ausgeführt und der button ansich reagiert nicht auf der anderen seite bleibt oder resetet sich der wert von gv wieder nach dem durchlauf von test1 wie der output von b2 zeigt.

danke schonmal im vorraus! :D
MFG Mr.101Freaking
BlackJack

@Mr.101Freaking: Die erste Funktion wird ausgeführt weil *Du* das machst. In Zeile 23 rufst Du die Funktion auf und übergibst deren *Rückgabewert* als `command`-Argument an `Button()`. Die Funktion gibt eine Zeichenkette zurück, die kann Tkinter dann aber nicht aufrufen wenn die Schaltfläche vom Benutzer angeklickt wird. Weil, nun ja weil Zeichenketten nicht aufrufbar sind:

Code: Alles auswählen

In [11]: '100'()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-b395290e35b7> in <module>()
----> 1 '100'()

TypeError: 'str' object is not callable
Was hätte da auch bei herauskommen sollen?

Du musst als `command`-Argument eine *Funktion* übergeben die kein Argument erwartet, den Tkinter ruft die ohne Argument auf. Wenn dadurch eine mit Argument aufgerufen werden soll, kann man sich mit `functools.partial()` aus einer Funktion und einem Wert so eine Funktion erstellen. Oder man verwendet einen ``lambda``-Ausdruck.

Zum zweiten Problem: Da wird nichts zurückgesetzt. `gv` auf Modulebene hat während des ganzen Programmablaufs (nach dem der Name definiert wurde) den gleichen Wert. Der wird nirgends geändert. Insbesondere Zeile 13 ändert das `gv` auf Modulebene nicht sondern definiert einen lokalen Namen `gv` innerhalb der Funktion. Such gar nicht erst nach einem Weg das `gv` auf Modulebene neu zu binden, denn das hat dort nichts zu suchen. Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Womit wir beim Lösungsansatz wären: objektorientierte Programmierung. Da kommt man bei GUI-Programmierung nicht drum herum wenn das eine saubere Lösung werden soll.
Mr.101Freaking
User
Beiträge: 6
Registriert: Samstag 30. Mai 2015, 14:34

Danke für die schnelle antwort
wenn ich dich richtig verstanden habe bastele ich mir jetzt eine klasse wo ich sowas wie das gv reinpacke, und dann zum änderen rausnehme und danach wieder reinwerfe
dann mache ich mich mal an die arbeit^^
wünsche noch einen schönen abend
BlackJack

@Mr.101Freaking: Das klingt zumindest komisch. Andererseits weiss ich jetzt nicht *wirklich* was Du da beschreibst. Das würde eigentlich eher alles innerhalb eines Objekts ablaufen.
Mr.101Freaking
User
Beiträge: 6
Registriert: Samstag 30. Mai 2015, 14:34

'tschuldigung bin heute abend nur begrenzt zurechnungsfähig hatte nen langen tag hinter mir
was ich meinte ist das ich kram, werte aus ner json auslese und dann mit denen in nem fenster rumrechen will am ende muss der kram dann wieder über nen button in die json das klappt auch alles halt bis aufs berechnen weil die berechneten werte nur lokale vars waren und ich die so nicht abspeichern konnte kann die ja schlecht aus nem label oder so wieder rausziehen dann köpft mich jeder der sich den code anguckt^^ aber ich hatte jetzt vor mit ne class zu schreiben wo ich einfach alles aus der json reinwerfe und es mir dann so rausfische wie ichs grade brauche, dann kann ich die neuen sachen wieder in die klasse schmeissen und dann schiebe ichs von da wieder zurück in die json
das wäre jetzt zumindest mein plan
Antworten