while True- Schleife in Tkinter beenden?

Fragen zu Tkinter.
Antworten
eagleone
User
Beiträge: 2
Registriert: Dienstag 22. Januar 2019, 16:39

Hallo,
Ich habe an meinen Rpi eine LED-Stripe angeschlossen.
Um diese zu steuern, habe ich mir ein kleines Pythonskript mit grafischer Oberfläche geschrieben, mit welchem man das Band steuern kann.
Neben normalen Farben, möchte ich auch einen Farbwechsel zur Auswahl haben,

Das Problem ist, dass dieser Farbwechsel mit einer while True: Schleife funktioniert und somit das restliche Programm (also das Fenster) blockiert. nachdem ich also auf "Start" drücke bleibt dieser Button gedrückt und man kann nichts mehr machen.

Nach zahlreichen Recherchen habe ich mittlerweile schon 1000 möglichkeiten ausprobiert, um meinen Code funktionieren zu lassen, doch komme ich nicht mehr weiter, da alles in Bugs und noch mehr Bugs endet.
Da ich leider noch ein blutiger Anfänger bin, wäre es hilfreich, wenn mir jemand sagen könnte, warum das nicht so funktioniert.

Code: Alles auswählen

import tkinter
import tkinter.messagebox
import pigpio
import RPi.GPIO as GPIO
import time
from tkinter import *

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(16,GPIO.OUT)
pi = pigpio.pi()

RED_PIN   = 18
GREEN_PIN = 23
BLUE_PIN  = 24

#Geschwindigkeit
STEPS     = 0.001


class Oberflaeche(tkinter.Frame):
        def __init__(self, master=None):
            tkinter.Frame.__init__(self, master)
            # Groesse des Fensters automatisch anpassen
            self.pack()

            

            

            #Lila
            self.lila_button = tkinter.Button(self, text="Lila", bg="purple", fg="black",anchor="center", heigh= 1, width = 8, command=self.lila)
            self.lila_button.grid(row = 2, column = 2, padx=20, pady=10)

            #Fade
            self.fade_button = tkinter.Button(self, text="Fade", bg="Black", fg="white",anchor="center", heigh= 1, width = 8, command=self.fade)
            self.fade_button.grid(row = 2, column = 3, padx=20, pady=10)

            #Beenden
            self.beenden = tkinter.Button(self, text="Beenden", bg="black", fg="white", anchor="center", heigh= 1, width = 8, command=self.beenden)
            self.beenden.grid(row = 1, column = 3, padx=20, pady=10)

            #Beenden Fade
            self.beendenfade = tkinter.Button(self, text="Fade Beenden", bg="black", fg="white", anchor="center", heigh= 1, width = 8, command=self.beendenfade)
            self.beendenfade.grid(row = 3, column = 3, padx=20, pady=10)



            self.grid_columnconfigure(0, weight=1)
            self.grid_columnconfigure(1, weight=1)
            self.grid_columnconfigure(2, weight=1)
            self.grid_columnconfigure(3, weight=1)
            self.grid_rowconfigure(0, weight=1)
            self.grid_rowconfigure(1, weight=1)
            self.grid_rowconfigure(2, weight=1)
            self.grid_rowconfigure(3, weight=1)


        #fading_an auf true setzen
        def fading_an():
                fading_an==True

        
        #Lila
        def lila(self):
                pi.set_PWM_dutycycle(18, 50)
                pi.set_PWM_dutycycle(23, 0)
                pi.set_PWM_dutycycle(24, 250)

        def fading_an():
                fading_an ==True
        #Fade an
        def fade(self):
                while fading_an ==True:
                        #Blau = GPIO 18
                        #Grün = GPIO 23
                        #Rot = GPIO 24
                        #Geschwindigkeit
                        SPEED     = 0.1

                        pi.set_PWM_dutycycle(18, 0)
                        pi.set_PWM_dutycycle(23, 0)
                        pi.set_PWM_dutycycle(24, 0)
                        time.sleep(1)

                        while True:
                                BRIGHTB1 = 250
                                BRIGHTR1 = 0
                                BRIGHTR2 = 250
                                BRIGHTG2 = 0
                                BRIGHTG3 = 250
                                BRIGHTB3 = 0
                                while BRIGHTB1 > -1 and BRIGHTR1 < 251:
                                        pi.set_PWM_dutycycle(18, BRIGHTB1)
                                        pi.set_PWM_dutycycle(24, BRIGHTR1)
                                        BRIGHTB1 = BRIGHTB1-3
                                        BRIGHTR1 = BRIGHTR1+3
                                        time.sleep(SPEED)

                                while BRIGHTR2 > -1 and BRIGHTG2 < 251:
                                        pi.set_PWM_dutycycle(24, BRIGHTR2)
                                        pi.set_PWM_dutycycle(23, BRIGHTG2)
                                        BRIGHTR2 = BRIGHTR2-1
                                        BRIGHTG2 = BRIGHTG2+1
                                        time.sleep(SPEED)

                                while BRIGHTG3 > -1 and BRIGHTB3 <251:
                                        pi.set_PWM_dutycycle(23, BRIGHTG3)
                                        pi.set_PWM_dutycycle(18, BRIGHTB3)
                                        BRIGHTG3 = BRIGHTG3-1
                                        BRIGHTB3 = BRIGHTB3+1
                                        time.sleep(SPEED)

        #Fade aus
        def beendenfade(self):
                fading_an == False

        #Beenden task
        def beenden(self):
            tkinter.messagebox.showinfo("Frage", "Willst du das Programm wirklich beenden?")
            root.destroy()
                









#Hauptfenster erstellen
root = tkinter.Tk()
#Eigenschaften fuer das Fenster setzen
root.title("Farbe wählen")
root.minsize(width=300, height=100)
#Instanz von Oberflaeche erstellen und Parent-Objekt festlegen
oberflaeche = Oberflaeche(master=root)
#Hauptschleife starten, um auf Klicks etc. zu reagieren
oberflaeche.mainloop()
Jedes Mal, wenn ich versuche das Skript zum Laufen zu bringen, ist entweder fading_an nicht definiert, oder ich erhalte 100 weitere Bugs.

Vielen Dank schon mal für eure Mühe
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@eagleone: bei GUIs darf es keine langlaufenden Methoden geben. Statt sleep modeliert man das mit after, wozu es schon 3423 Beiträge hier im Forum gibt.

Sternchenimporte sind schlecht, Du benutzt aber auch keine der so importierten Namen.
`as` bei Import dient dazu, Namen umzubenennen. GPIO bleibt aber GPIO, `as` ist also unnötig.
Warnings sind dazu da, dass man sie behebt, nicht dass man sie ignoriert. Hier mußt Du also vor dem Abbruch des Programms GPIO.cleanup aufrufen. Warum mischst Du RPi.GPIO mit pigpio?

Eingerückt wird immer mit 4 Leerzeichen pro Ebene. Da ist bei Dir einiges durcheinander, was den Code sehr schwer lesbar macht. Genauso die vielen Leerzeilen.

Bei fading_an fehlt das self und die Variable innerhalb der Funktion fading_an ist nicht definiert. Ein Vergleich macht an der Stelle auch keinen Sinn.

In `beenden` wird `root` benutzt, ohne dass es übergeben wird, das sollte nicht sein. Um solche Fehler zu vermeiden, muß alles ab `# Hauptfenster erstellen` auch in eine Funktion, die man üblicherweise `main` nennt, damit es keine globalen Variablen gibt.
Antworten