Seite 1 von 1
Tkinter UnboundLocalError
Verfasst: Montag 21. Dezember 2020, 14:24
von Boruto_2200
Hey Leute, ich hätte da eine Frage...
Ich schreibe gerade einen CPS-Tester mit Tkinter, aber immer, wenn ich ihn starte, zeigt er mir "UnboundLocalError: local variable 'CPS' referenced before assignment" an. Ich verstehe das einfach nicht... Ich programmiere jetzt schon ca. 1 Jahr mit Python, und so etwas ist mir eigentlich noch nie passiert...

Wäre gut, wenn mir einer helfen könnte...
Hier noch der ganze Code:
from tkinter import *
window = Tk()
c = Canvas(window, width = 800, height = 800)
c.pack
CPS = 0
def CPSclock():
CPS = CPS + 1
cps_button = Button(window, text = 'Click Me!', width = 500, height = 150, command = CPSclock)
cps_button.pack()
mainloop()
Vielen Dank

Re: Tkinter UnboundLocalError
Verfasst: Montag 21. Dezember 2020, 14:50
von miel9
Soweit Funktioniert das:
Code: Alles auswählen
from tkinter import *
window = Tk()
c = Canvas(window, width = 1, height = 1)
c.pack
cps = 0
def CPSclock():
global cps
cps += 1
cps_button = Button(window, text = 'Click Me!', width = 500, height = 150, command = CPSclock)
cps_button.pack()
b = Button(window, text='A', command=pr).pack()
mainloop()
Bei dir hatte das wegen Python's Globale-und-Lokale-Variablen-Generve nicht Funktioniert. Das hat mich auch schon mehrmals in den Wahnsinn getrieben

.
Re: Tkinter UnboundLocalError
Verfasst: Montag 21. Dezember 2020, 14:55
von __blackjack__
@Boruto_2200: Vergiss ``global`` gleich wieder. Das schafft mehr Probleme als es löst.
Wenn man in einer Funktion/Methode eine Zuweisung an einen Namen hat, dann ist das ein lokaler Name. `CPS` in `CPSclock()` ist also ein lokaler Name der nichts mit dem Namen `CPS` auf Modulebene zu tun hat.
`CPS` auf Modulebene sollte es auch gar nicht geben. Genau wie alles andere was da ausser dem Import und der Funktionsdefinition steht. Das Hauptprogramm gehört in eine Funktion. Üblicherweise wird die `main()` genannt.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).
Funktions- und Methodennamen werden üblicherweise nach der Tätigkeit benannt die sie durchführen. Damit kann man sie besser von eher ”passiven” Werten unterscheiden.
Sternchen-Importe sind Böse™. Da holt man sich gerade bei `tkinter` fast 200 Namen ins Modul von denen nur ein kleiner Bruchteil verwendet wird. Auch Namen die gar nicht in `tkinter` definiert werden, sondern ihrerseits von woanders importiert werden. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.
Bei jeder nicht-trivialen GUI braucht man objektorientierte Programmierung. Also eigene Klassen.
Re: Tkinter UnboundLocalError
Verfasst: Montag 21. Dezember 2020, 15:57
von Sirius3
*-Importe sollte man nicht verwenden. c.pack sollte man aufrufen. Variablennamen sollten aussagekräftig sein. Und für Zustand in GUIs braucht man Klassendefinitionen.
Code: Alles auswählen
import tkinter as tk
class MainWindow(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.canvas = tk.Canvas(self, width=800, height=800)
self.canvas.pack()
tk.Button(self, text='Click Me!', width=500, height=150, command=self.cps_clock).pack()
self.cps = 0
def cps_clock(self):
self.cps += 1
def main():
window = MainWindow()
window.mainloop()
if __name__ == '__main__':
main()
Re: Tkinter UnboundLocalError
Verfasst: Montag 21. Dezember 2020, 18:40
von Boruto_2200
Vielen Dank für eure schnelle Hilfe
Jetzt habe ich aber ein weiteres Problem: Nämlich die ständige Ausgabe des Wertes 'cps'...
Ich habe schon getan, was ich konnte, aber es funktioniert nicht wirklich... Ich habe einen Exitbutton gemacht, mit dem man das Programm beenden kann; vorher bekommt man aber über das Shell den Wert 'cps' ausgegeben. Das Problem ist die Ausgabe von den cps; Es soll jede Sekunde die CPS der vergangenen Sekunde geben und die durchschnittliche cps ca. alle 5 sek aktualisieren. Ich habe jetzt schon einiges ausprobiert, das ganze hat aber nicht funktioniert....
Hier wäre noch der aktuelle Code:
Code: Alles auswählen
from tkinter import *
window = Tk()
c = Canvas(window, width = 1, height = 1)
c.pack
cps = 0
def pr():
global cps
cps += 1
def exitx():
text = 'CPS: ' + str(cps)
print(text)
window.destroy()
b = Button(window, text='A', command=pr).pack()
exit_ = Button(window, text = 'Exit', command = exitx).pack()
mainloop()