Labels aktualisieren

Fragen zu Tkinter.
Antworten
matze946
User
Beiträge: 2
Registriert: Donnerstag 16. Mai 2019, 10:23

Hey zusammen!
Ich stehe zur Zeit vor folgender Aufgabe:
Ich soll Werte von zwei Ultraschallsensoren einlesen und mir in einer GUI jeweils entweder ein rotes Label oder ein grünes Label (abhängig von den Werten der Ultraschallsensoren) anzeigen lassen.
Jetzt zu meinem Problem:
Das einlesen der Werte von den Sensoren funktioniert einwandfrei. Jedoch habe ich es noch nicht geschafft die Farbe meiner beiden Labels zu änder ohne das Programm zu schließen. Im Moment ist die GUI eine Sekunde aktiv, dann schließt sie sich und öffnet sich wieder (mit aktualisierten Labels).
Wie bekomme ich es jetzt noch hin, dass sich die Labels aktualisieren ohne, dass ich die GUI dauernd schließen muss?
Danke schon mal im Vorraus.
Matze946

hier schonmal mein Code

Code: Alles auswählen

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

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

Trig1 = 18
Echo1 = 24
Echo2 = 25

GPIO.setup(Trig1, GPIO.OUT)
GPIO.setup(Echo1, GPIO.IN)
GPIO.setup(Echo2, GPIO.IN)

def MesseDistanz():
        GPIO.output(Trig1, True)
        time.sleep(0.00001)
        GPIO.output(Trig1, False)
       
        Startzeit1=time.time()
        Stopzeit1=time.time()
        
        while GPIO.input(Echo1) == 0:
                Startzeit1 = time.time()
                
        while GPIO.input(Echo1) == 1:
                Stopzeit1 = time.time()
                
        Laufzeit1 = Stopzeit1 - Startzeit1
        Distanz1 = (Laufzeit1 * 34300) / 2
        
        GPIO.output(Trig1, True)
        time.sleep(0.00001)
        
        GPIO.output(Trig1, False)
        
        Startzeit2=time.time()
        Stopzeit2=time.time()
        
        while GPIO.input(Echo2) == 0:
                Startzeit2 = time.time()
                
        while GPIO.input(Echo2) == 1:
                Stopzeit2 = time.time()
                
        Laufzeit2 = Stopzeit2 - Startzeit2
        Distanz2 = (Laufzeit2 * 34300) / 2
        
        return [Distanz1, Distanz2]
    
if __name__ == '__main__':
  
        try:
            while True:
                Ergebnis = MesseDistanz()
                #print("Entfernung1 = %.1f cm  Entfernung2 = %.1f cm" % (Ergebnis[0], Ergebnis[1]))
                
                root= Tk()
                leftFrame=Frame(root, width=600, height=480)
                leftFrame.grid(row=0, column=0, padx=2, pady=2)
        
                rightFrame=Frame(root, width=200, height=480)
                rightFrame.grid(row=0, column=1, padx=2, pady=2)
                
                if Ergebnis[0]> 10.00:
                    
                    s1 = Label(leftFrame,font=("Arial","20"), width=5, bg="#00FF00")
                    s1.grid(row=0, column=1, padx=2, pady=2)
                    #s1.after(1000, s1.destroy)
                if Ergebnis[0]< 10.00:
                   
                    s1 = Label(leftFrame,font=("Arial","20"), width=5, bg="#FF0000")
                    s1.grid(row=0, column=1, padx=2, pady=2)
                    #s1.after(1000, s1.destroy)
                if Ergebnis[1]> 10.00:
                    
                    
                    s2 = Label(leftFrame,font=("Arial","20"), width=5, bg="#00FF00")
                    s2.grid(row=1, column=1, padx=2, pady=2)
                    #s2.after(1000, s2.destroy)
                if Ergebnis[1]< 10.00:
                     
                    s2 = Label(leftFrame,font=("Arial","20"), width=5, bg="#FF0000")
                    s2.grid(row=1, column=1, padx=2, pady=2)
                    #s2.after(1000, s2.destroy)
                
                
                #root.update_idletasks()
                root.after(1000, root.destroy)
                root.update_idletasks()
                root.mainloop()
                
        except KeyboardInterrupt:
                print("Messung abgebrochen")
                GPIO.cleanup()
                
        
 
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@matze946: eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 4 und mal 8. 8 ist viel zu viel, um es noch schnell lesen zu können.
`as` benutzt man beim Importieren um einen Namen umzubenennen, aber bei Dir bleibt GPIO GPIO, das `as` ist also überflüssig.
*-Importe vermeiden, tkinter wird üblicherweise als `import tkinter as tk` importiert und alle Namen aus tkinter über tk.xyz angesprochen.
Konstanten schreibt man üblicherweise KOMPLETT_GROSS, Variablennamen und Funktionen klein_mit_unterstrich.
Warnungen sind dazu da, dass man die Ursache beseitigt, nicht dass man sie abschaltet. Dazu gehört auch GPIO.cleanup in einen finally-Block statt ins except.

Alles was im Block nach `if __name__ == '__main__':` steht, sollte in eine Funktion wandern, die üblicherweise main genannt wird.
MesseDistanz macht zwei mal das selbe, was man gut in eine Funktion auslagern könnte, die zwei mal aufgerufen wird.
Statt des Busy-Wait auf die GPIO-Inputs solltest Du wait_for_edge mit einem sinnvollen Timeout verwenden.

Um GUI-Programme richtig zu schreiben, braucht man eigentlich Klassendefinitionen. Bei Dir kommt hinzu, dass Du einen Hintergrundprozess (Messen der Distanz) und einen Vordergrundprozess (Anzeigen der GUI) hast. Dazu mußt Du Dich zusätzlich noch mit Threads, nebenläufiger Programmierung, Queues zur Kommunikation und `after` zur Aktualisierung der GUI auseinandersetzen.
Also statt das aktuelle Fenster immer wieder zu zerstören und neu zu bauen, einmal das Fenster aufbauen, und mit after abfragen, ob es eine neue Distanzmessung gibt. Diese Distanzmessung findet in einem separaten Thread statt, und die Ergebnisse werden in eine Queue geschrieben.
matze946
User
Beiträge: 2
Registriert: Donnerstag 16. Mai 2019, 10:23

Oke danke dir schon mal für deine schnelle Antwort :) Ich werde es jetzt mal so probieren wie du es gesagt hast. Sorry, dass noch relativ viele Fehler im Code sind bin ziemlich neu in der Python Welt.
Antworten