Übergabe einer Variable bei Änderung der Button-Beschriftung

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
Epidauros
User
Beiträge: 20
Registriert: Freitag 4. September 2020, 13:47

Hallo Schwarmwissen,
ich hab eine Aufgabe zu lösen, bei der die Beschriftung eines Button auf Knopfdruck geändert werden soll.
Dazu soll in Abhängigkeit von der aktuellen Beschriftung eine Variable gesetzt werden.
Das klappt alles ganz gut und innerhalb der Routine wird der erwartete Wert der Variable ausgegeben.

Allerdings gilt diese Variable nur innerhalb der Routine, obwohl ich der Routine die Variable mit übergebe.
Irgendwo mache ich mir einen Knoten, den ich nicht sehe.
Wer kann helfen?

- Ich sage schon einmal herzlich Danke!

Code: Alles auswählen

from tkinter import *

Variable = 0b11000011
def Aufgabe_loesen(Variable):
    Taste = Button(pady="12", width="20", bg='azure',text="Text3")
    Taste.grid(row=3,column=2)

    def button_click(event): # Die Beschriftung der Taste rolliert bei Druck
        if Taste["text"] == "Text1":
           Taste["text"] = "Text2"
           Variable = 0b10000010 # Dieser Wert wird später gebraucht ..

        elif Taste["text" ] == "Text2":
           Taste["text"] = "Text3"
           Variable = 0b10001001 # oder dieser Wert ....
            
        elif Taste["text" ] == "Text3":
           Taste["text"] = "Text1"
           Variable = 0b11000011 # oder dieser.
            
        print('Aktueller Wert: ' + str(bin(Variable)))
        # Die Variable in Abhängigkeit von dem Button wird richtig ausgegeben
        # Der Wert soll an anderer Stelle  weiterverarbeitet werden, muss also übergeben werden
  
    Taste.bind("<Button-1>", button_click)

Aufgabe_loesen(Variable)

print('Aktueller Wert: ' + str(bin(Variable)))
# hier kommt immer der vor der Tastenabfrage angelegte Wert heraus aus der ersten Zeile. 
# Die Änderung des Wertes durch die Routine wurde hier nicht übernommen.

Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Lokale Variablen heißen "lokal" weil man ihnen andere Werte zuweisen kann, ohne dass das außerhalb der Funktion irgendwelche Störungen verursacht.
Will man tatsächlich einen Zustand über das Ende der Funktion bewahren, braucht man Klassendefinitionen, was bei GUI-Programmen meist der Fall ist.
*-Importe sind böse, weil man nicht nachvollziehen kann, woher welcher Name stammt.
Funktionen sollten nicht innerhalb von Funktionen definiert werden, da das Programm dadurch schwierig zu testen ist.
Bei Dir fehlt der Code zum Erzeugen des Hauptfensters und der Aufruf von mainloop. Zum Zeitpunkt Deiner Print-Ausgabe ganz am Schluß hatte noch kein Nutzer die Gelegenheit eine Taste zu drücken. So funktionieren GUI-Programme nicht. Man hat keinen linearen Programmablauf sondern kann nur auf Aktionen reagieren.
Bei Buttons erwartet der Nutzer ein bestimmtes Verhalten, dass er/sie z.B. die Taste drücken und wieder Loslassen kann. Dieses Verhalten wird durch die Verwendung von `bind` unterlaufen.
Variablennamen und Funktionen schreibt man komplett klein.

Code: Alles auswählen

import tkinter as tk

class Application(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.variable = 0b11000011
        self.taste = tk.Button(self, pady=12, width=20, bg='azure', text="Text3", command=self.press_button)
        self.taste.pack()
        
    def press_button(self):
        if self.taste["text"] == "Text1":
           self.taste["text"] = "Text2"
           self.variable = 0b10000010
        elif self.taste["text"] == "Text2":
           self.taste["text"] = "Text3"
           self.variable = 0b10001001
        elif self.taste["text"] == "Text3":
           self.taste["text"] = "Text1"
           self.variable = 0b11000011
        print(f'Aktueller Wert: {self.variable:b}')

def main():
    application = Application()
    application.mainloop()
    print(f'Aktueller Wert: {application.variable:b}')

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

Eine Variante, die den Zustand in einer Datenstruktur/einem Iterator abbildet, statt in Code:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk
from itertools import cycle


class Application(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.states = cycle(
            [
                ("Text1", 0b11000011),
                ("Text2", 0b10000010),
                ("Text3", 0b10001001),
            ]
        )
        #
        # TODO Ist `text` und `variable` hier richtig, oder stimmt das in
        #   Wahrheit mit einem der Paare in `states` überein?  Dann sollte man
        #   das *dort* her holen, statt hier im Code zu wiederholen.
        #
        self.variable = 0b11000011
        self.taste = tk.Button(
            self,
            pady=12,
            width=20,
            bg="azure",
            text="Text3",
            command=self.on_button,
        )
        self.taste.pack()

    def on_button(self):
        self.taste["text"], self.variable = next(self.states)
        print(f"Aktueller Wert: {self.variable:b}")


def main():
    application = Application()
    application.mainloop()
    print(f"Aktueller Wert: {application.variable:b}")


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten