Verstehe Fehlermeldung nicht

Fragen zu Tkinter.
Antworten
reiwe3
User
Beiträge: 12
Registriert: Samstag 21. August 2021, 14:46

hallo,
zuerst den Code:
import tkinter as tk
from functools import partial
def count_call_back(count_label,time_base, led_blinker, counter_value=1):
count_label["text"] = counter_value
count_label.after(int(time_base*1000), count_call_back, count_label, led_blinker, counter_value + 1,time_base)
switch_label_color(counter_value, led_blinker)

def switch_label_color(counter_value, led_blinker):
if counter_value % 2 == 1: # Farbumschlag des Labels
color = "green"
else:
color = "red"
led_label["bg"] = color

def start_action(count_label,led_blinker,eingabe1): # Zeitbasis wird erzeugt, Eingabefehler abgefangen
try:
time_base = float(eingabe1.get())
except ValueError:
count_label['text'] = "Nur Zahlen!"
else:
count_call_back(count_label,led_blinker,time_base)

def main():
root = tk.Tk()
root.title(" Zeit-Zähler und Blinker ")
root.minsize(width=600, height=500)
count_label = tk.Label(root, fg="green",bg="white",font=("Arial", 22),width=10,height=2)
count_label.pack(padx=10, pady=10)
led_blinker=tk.Label(root,text="LED",font=("Arial",14), width=10,height=3 )
led_blinker.pack(padx=20, pady= 20)
text1_label=tk.Label(root,text=" Zeitbasis > 0.09 Sek. eingeben",fg="blue")
text1_label.pack()
eingabe1=tk.Entry(root)
eingabe1.pack()
start_button=tk.Button(root,text=" Start ",fg="blue",bg="yellow",width=20,command=partial(start_action,count_label, led_blinker,eingabe1))
start_button.pack(padx=20,pady=85)
ende_button=tk.Button(root, text="Ende", fg="red", bg="white",width=20,height=1, command=root.destroy).pack(padx=20, pady=80)
root.mainloop()

if __name__ == "__main__":
main()
----------------------------------------------------------------------
folgende Fehler-Meldung :
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.2800.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\rewel\Documents\Python\Demo\g-test.10xx.py", line 21, in start_action
count_call_back(count_label,led_blinker,time_base)
File "C:\Users\rewel\Documents\Python\Demo\g-test.10xx.py", line 5, in count_call_back
count_label.after(int(time_base*1000), count_call_back, count_label, led_blinker, counter_value + 1,time_base)
TypeError: unsupported operand type(s) for *: 'Label' and 'int'
>>>

vielleicht weiss jemand rat ?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@reiwe3: In der Zeile kommt ja nur ein ``*``-Operator vor. Und da versuchst Du ein `Label`-Objekt mit einer ganzen Zahl zu multiplizieren. Das geht halt nicht. Das Label ist das zweite Argument der Funktion. Und da übergibst Du, beziehungsweise lässt Du ein `Label`-Objekt übergeben, wo es eine Zahl sein sollte. Da ist genau die gleiche Zeile Schuld dran. Man muss Argument schon in der Reihenfolge übergeben, in der sie erwartet werden.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@reiwe3,

In der Funktionsdeklaration von "count_call_back" stimmte die Reihenfolge der Parameter nicht mit der Reihenfolge im Funktionsaufruf überein.
So funktioniert es:

Code: Alles auswählen

import tkinter as tk
from functools import partial


def count_call_back(count_label, time_base, led_blinker, counter_value=1):
    count_label["text"] = counter_value
    count_label.after(int(time_base * 1000), count_call_back, count_label, time_base, led_blinker, counter_value + 1)
    switch_label_color(counter_value, led_blinker)


def switch_label_color(counter_value, led_blinker):
    if counter_value % 2 == 1:  # Farbumschlag des Labels
        color = "green"
    else:
        color = "red"
    led_blinker["bg"] = color


def start_action(count_label, led_blinker, eingabe1):  # Zeitbasis wird erzeugt, Eingabefehler abgefangen
    try:
        time_base = float(eingabe1.get())
    except ValueError:
        count_label["text"] = "Nur Zahlen!"
    else:
        count_call_back(count_label, time_base, led_blinker)


def main():
    root = tk.Tk()
    root.title(" Zeit-Zähler und Blinker ")
    root.minsize(width=600, height=500)
    count_label = tk.Label(root, fg="green", bg="white", font=("Arial", 22), width=10, height=2)
    count_label.pack(padx=10, pady=10)
    led_blinker = tk.Label(root, text="LED", font=("Arial", 14), width=10, height=3)
    led_blinker.pack(padx=20, pady=20)
    text1_label = tk.Label(root, text="  Zeitbasis > 0.09 Sek. eingeben", fg="blue")
    text1_label.pack()
    eingabe1 = tk.Entry(root)
    eingabe1.pack()
    start_button = tk.Button(root, text=" Start ", fg="blue", bg="yellow", width=20, command=partial(start_action, count_label, led_blinker, eingabe1))
    start_button.pack(padx=20, pady=85)
    ende_button = tk.Button(root, text="Ende", fg="red", bg="white", width=20, height=1, command=root.destroy)
    ende_button.pack(padx=20, pady=80)
    root.mainloop()


if __name__ == "__main__":
    main()
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@reiwe3: Upsi, Korrektur: Die Reihenfolge ist beim ersten Aufruf der Funktion auch schon falsch. Oder halt umgekehrt: Die Reihenfolge der Argumente ist im Funktionskopf falsch.

In `switch_label_color()` ist auch ein Fehler: Da wird das `led_blinker`-Argument nicht verwendet, dafür in der Funktion ein `led_label`, welches es nicht gibt.

Namen sollte man keine Nummern anhängen.

`ende_button` wird an den Wert `None` gebunden, was keinen Sinn macht.

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk
from functools import partial


def switch_label_color(led_label, counter_value):
    led_label["bg"] = ["red", "green"][counter_value % 2]


def count_callback(count_label, led_blinker, time_base, counter_value=1):
    count_label["text"] = counter_value
    switch_label_color(led_blinker, counter_value)
    count_label.after(
        int(time_base * 1000),
        count_callback,
        count_label,
        led_blinker,
        time_base,
        counter_value + 1,
    )


def start_action(count_label, led_blinker, eingabe):
    try:
        time_base = float(eingabe.get())
    except ValueError:
        count_label["text"] = "Nur Zahlen!"
    else:
        count_callback(count_label, led_blinker, time_base)


def main():
    root = tk.Tk()
    root.title("Zeit-Zähler und Blinker")
    root.minsize(width=600, height=500)
    
    count_label = tk.Label(
        root, fg="green", bg="white", font=("Arial", 22), width=10, height=2
    )
    count_label.pack(padx=10, pady=10)
    
    led_blinker = tk.Label(
        root, text="LED", font=("Arial", 14), width=10, height=3
    )
    led_blinker.pack(padx=20, pady=20)
    
    tk.Label(
        root, text="Zeitbasis > 0.09 Sek. eingeben", fg="blue"
    ).pack()
    
    eingabe = tk.Entry(root)
    eingabe.pack()
    
    tk.Button(
        root,
        text="Start",
        fg="blue",
        bg="yellow",
        width=20,
        command=partial(start_action, count_label, led_blinker, eingabe),
    ).pack(padx=20, pady=85)
    
    tk.Button(
        root,
        text="Ende",
        fg="red",
        bg="white",
        width=20,
        command=root.destroy,
    ).pack(padx=20, pady=80)
    
    root.mainloop()


if __name__ == "__main__":
    main()
Es ist ein bisschen unpraktisch, dass der Start-Button aktiv bleibt, und man so mehrere Zähl+Blinkvorgänge starten kann.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Es ist ein bisschen unpraktisch, dass der Start-Button aktiv bleibt, und man so mehrere Zähl+Blinkvorgänge starten kann.
das ist ein Feature. So kann man nämlich einen unregelmäßigen Rhythmus einstellen :)
reiwe3
User
Beiträge: 12
Registriert: Samstag 21. August 2021, 14:46

besten danke rogerb und __blackjack__
ich habe den Fehler gesehen, das mit der noch aktiven start - Taste hab ich jetzt auch erkannt.
Danke zusammen !
Antworten