Guten Morgen,
ich möchte mir TKinter etwas genauer anschauen. Dazu habe ich im Netz diese Seite gefunden:
http://www.python-kurs.eu/tkinter_labels.php
In diesem Abschnitt geht es um Labels. Weiter unten unter der Überschrift "Dynamischer Inhalt in einem Label-Widget" gibt es ein kleines Beispiel mit einem Counter. In diesem Beispiel gibt es einen Befehl (in Funktion "counter_label"), welcher bei meinem MacBook nicht funktioniert. Bei Windows funktioniert er problemlos. Bei beiden Betriebssystemen habe ich es nochmal per Copy&Paste versucht, um Tippfehler auszuschließen.
Die besagte Zeile lautet: label.config(text=str(counter))
Beim Mac bekomme ich die Meldung, dass .config nicht in der Bibliothek vorhanden wäre.
Weiß hier jemand weiter ?
Grüße,
lordzwieback
x.config funktioniert nicht
-
- User
- Beiträge: 55
- Registriert: Montag 2. März 2015, 14:35
- Kontaktdaten:
@lordzwieback: Zeig mal bitte den kompletten Quelltext der diesen Fehler zur Folge hat und auch den kompletten Traceback dazu. Das sollte nicht passieren.
Allerdings ist der Quelltext auf der verlinkten Seite nicht wirklich schön mit dem ``global``.
Allerdings ist der Quelltext auf der verlinkten Seite nicht wirklich schön mit dem ``global``.
-
- User
- Beiträge: 55
- Registriert: Montag 2. März 2015, 14:35
- Kontaktdaten:
Hey, sorry das ich jetzt erst antworte, bin eben erst heimgekommen.
Der komplette Code:
Und der Traceback dazu:
Sorry falsch ich den Traceback falsch interpretiert hab.
Der komplette Code:
Code: Alles auswählen
from tkinter import *
counter = 0
def counter_label(label):
def count():
global counter
counter += 1
label.config(text=str(counter))
label.after(1000, count)
count()
root = Tk()
root.title("Counting seconds")
label = Label(root, fg="green").pack()
counter_label(label)
button = Button(root, text="stop", width=25, command=root.destroy()).pack()
root.mainloop()
Code: Alles auswählen
/Library/Frameworks/Python.framework/Versions/3.4/bin/python3.4 /Users/***/PycharmProjects/tkinter/count_seconds.py
Traceback (most recent call last):
File "/Users/***/PycharmProjects/tkinter/count_seconds.py", line 16, in <module>
counter_label(label)
File "/Users/***/PycharmProjects/tkinter/count_seconds.py", line 11, in counter_label
count()
File "/Users/***/PycharmProjects/tkinter/count_seconds.py", line 9, in count
label.config(text=str(counter))
AttributeError: 'NoneType' object has no attribute 'config'
Process finished with exit code 1
@lordzwieback: Der Code würde unter Windows die gleiche Ausnahme zur Folge haben. Lass Dir `label` mal ausgeben und wenn Du schon dabei bist auch `button`. Und dann schau Dir den Unterschied zu der verlinkten Webseite an und was *dort* an die Namen gebunden wird.
-
- User
- Beiträge: 55
- Registriert: Montag 2. März 2015, 14:35
- Kontaktdaten:
Alles klar, hab die Fehler gefunden, danke. War wohl blind vom vielen Draufglotzen..
Code: Alles auswählen
from tkinter import *
from tkinter import messagebox
from time import sleep
fehlversuche = 0
global lockedTime
lockedTime=0
variablen = {}
root2 = Tk()
w, h = 800, 800
root2.geometry("%dx%d+0+0" % (w, h))
root2.configure(bg="dark red")
root2.resizable(width=0, height=0)
canvas_width = w
canvas_height = h
variablen = {"fehlversuche": fehlversuche, "root2": root2,"lockedTime": lockedTime}
masterPasswordVar ="1234"
widget1 = Label(root2, justify=LEFT, fg = "dark red", bg = "#fffacd", font = "Helvetica 32 bold italic", text="Please enter your password!").place(x=100,y=1)
widget2 = Label(root2, justify=LEFT, fg = "dark red", bg ="#00FFFF", font = "Helvetica 32 bold italic", text="!!!Wrong password!!!")
def count(var):
widget3 = Label(root2, justify=LEFT, fg = "dark red", bg ="#00FFFF", font = "Helvetica 32 bold italic", text=str(var["lockedTime"])).place(x=100,y=60)
while True:
print(str(var["lockedTime"]))
var["lockedTime"] -=1
str(var["lockedTime"])
widget3.config(text=str(var["lockedTime"])) # Hier ist der Fehler!
sleep(1)
if var["lockedTime"] ==50: # Damit die Shleife früher abbricht und ich nicht so lange warten muss
break
def confirmMasterPass(var):
print("LockedTime: " + str(var["lockedTime"]))
if var["lockedTime"]==0:
print("MasterPassword is checking...")
if (entryMasterPassword.get()==masterPasswordVar):
print("MasterPassword true")
print("start mainbody...")
root2.destroy()
main()
else:
print("Fails: " + str(var["fehlversuche"]))
var["fehlversuche"] += 1
entryMasterPassword.delete(0,"end")
print("MasterPassword false")
widget2.place(x=220,y=340)
if var["fehlversuche"] == 3:
var["lockedTime"]=60
messagebox.showerror("Passwort falsch!", "Too much fails!!! The programm is locked for 60s")
count(var)
else:
messagebox.showerror(title="Informtion", message="Wrong Password")
else:
messagebox.showerror(title="Informtion", message="The programm is still locked for: "+ str(var["lockedTime"]))
entryMasterPassword = Entry(master=root2, bg="#fffacd")
confirmMasterPassword=Button(master=root2, text="Confirm password", command=lambda:confirmMasterPass(variablen))
exitB = Button(master=root2, text="Close programm", command=lambda: root2.destroy())
exitB.place(x=350,y=700, width=150, height=20)
entryMasterPassword.place(x=325, y=400, width=200, height=40)
confirmMasterPassword.place(x=350, y=450, width=150, height=20)
confirmMasterPassword.configure(bg="#7cfc00")
exitB.configure(bg="#7cfc00")
root2.bind("<Return>", lambda e: confirmMasterPass(variablen))
def main():
print("succes start mainbody")
root = Tk()
w, h = 800, 800
root.geometry("%dx%d+0+0" % (w, h))
root.configure(bg="green")
canvas_width = w
canvas_height = h
root.resizable(width=0, height=0)
widget50 = Label(root, justify=LEFT, fg = "blue", bg = "#fffacd", font = "Helvetica 32 bold italic", text="Welcome back!").place(relx=0.3,y=1)
exitB2 = Button(master=root, text="Close programm", command=lambda: root.destroy())
exitB2.place(x=350,y=750, width=150, height=20)
root.mainloop()
root2.mainloop()
1 Sache vorweg: Der code ist nicht perfekt, ich sitzte erst seit gestern dran und mache manche Sachen erst später.
EDIT: Danke für die schnelle Antwort.
Code: Alles auswählen
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Tobias\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
return self.func(*args)
File "C:\Users\Tobias\Desktop\python\123.py", line 90, in <lambda>
root2.bind("<Return>", lambda e: confirmMasterPass(variablen))
File "C:\Users\Tobias\Desktop\python\123.py", line 67, in confirmMasterPass
count(var)
File "C:\Users\Tobias\Desktop\python\123.py", line 37, in count
widget3.config(text=str(var["lockedTime"])) # Hier ist der Fehler!
AttributeError: 'NoneType' object has no attribute 'config'
Ich habe gerade nochmal selbst gesucht. Meine Guete. Die Dokumentation rund um tkinter ist ein solcher Cluster-Fuck, es ist schon beeindruckend.
@timm4444 du glaubst (oder behandelst es zumindest so), das place() das Widget zurueck liefern wuerde. Tut es nicht. Es liefert None. Und konsequenterweise kracht es dann.
Separier die Anlage eines Widgets von seiner Platzierung, und es funktioniert. Und dann der uebliche Hinweis: place ist Mist. Grosser Mist. Benutz es nicht, sondern bau dein Layout mit grid und pack auf (wobei man die, wie alle layout-Methoden, nicht in einem Container, also einem Fenster oder einem Frame, mischen darf).
@timm4444 du glaubst (oder behandelst es zumindest so), das place() das Widget zurueck liefern wuerde. Tut es nicht. Es liefert None. Und konsequenterweise kracht es dann.
Separier die Anlage eines Widgets von seiner Platzierung, und es funktioniert. Und dann der uebliche Hinweis: place ist Mist. Grosser Mist. Benutz es nicht, sondern bau dein Layout mit grid und pack auf (wobei man die, wie alle layout-Methoden, nicht in einem Container, also einem Fenster oder einem Frame, mischen darf).
Ok, danke, jetzt funtioniert es, nachdem ich noch ein "root.update()" hinzugefügt habe.
Frage: Wieso geht nicht, aber getrennt?
Frage: Wieso geht
Code: Alles auswählen
abc =label().place()
Habe ich doch gesagt. place liefert None zurueck. Das sagt doch auch dein Fehler.
Code: Alles auswählen
AttributeError: 'NoneType' object has no attribute 'config'
- __blackjack__
- User
- Beiträge: 13004
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@timm4444: Das `root.update()` ist falsch und gefährlich. GUI-Programmierung ist nicht linear, da arbeitet man mit Ereignissen. Und für jede nicht-triviale GUI kommt man um objektorientierte Programmierung (OOP) nicht herum. Also eigene Klasse(n) schreiben.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis