While Schleife lässt GUI abstürzen

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
Julianonl
User
Beiträge: 2
Registriert: Donnerstag 18. April 2019, 13:47

Hi ich bin noch ein ziemlicher Python Anfänger und gerade dabei ein Skript zu schreiben das über Rasberry ein Schildkröten aussengehege steuern soll. Die grundlegenden Funktionen dabei sind das es eine Wärmematte und Wärmelampe Temperatur und Zeitabhänig steuert.
Damit die Temperatur immer aktuell ist habe ich für die Abfrage eine While Schleife benutzt das Problem ist jetzt jedoch das wenn die while Schleife startet sich meine GUI aufhängt.

Code: Alles auswählen

      def baw1():
            import temp1
            from temp1 import temp1
            e5 = self.Entry2.get()
            e1 = self.Text1.get()
            e2 = self.Text2.get()
            e3 = self.Text1_2.get()
            e4 = self.Text1_3.get()


            e5 = int(e5)
            print(e5)
            e4 = int(e4)
            print(e4)
            e3 = int(e3)
            print(e3)
            e2 = int(e2)
            print(e2)
            e1 = int(e1)
            print(e1)
            print(wa)

        
 

            while temp1 < e5 and wa == "auto":
                currTime = datetime.datetime.now()
                print(currTime)
                        

                    
                if wa == "auto":

                    auto_on = datetime.datetime(year=2019, month=1, day=12, hour=e1, minute=e2, second=0)
                    auto_off = datetime.datetime(year=2019, month=1, day=12, hour=e3, minute=e4, second=0)
                    currTime = datetime.datetime.now()
                    print(currTime)
                    time.sleep(1)
                    

                    
            
                    if (currTime.hour - auto_on.hour == 0 and                       
                        currTime.minute - auto_on.minute == 0 and                        
                        currTime.second - auto_on.second == 0):
                        print("On")
                        time.sleep(1)


                      
                            

                                                
                    elif (currTime.hour - auto_off.hour == 0 and                        
                          currTime.minute - auto_off.minute == 0 and                        
                        currTime.second - auto_off.second == 0):    
                        print("Off")
                        time.sleep(1)
Vielen Dank schon mal in Voraus.
Benutzeravatar
__blackjack__
User
Beiträge: 14042
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Julianonl: Keiner von den Werten die in der Schleifenbedingung verwendet werden ändert sich innerhalb der Schleife. Das heisst die wird entweder gar nicht durchlaufen, oder aber sie ist eine Endlosschleife und blockiert damit die GUI, weil deren GUI-Hauptschleife nicht läuft.

Die Namen sind durchgehen sehr schlecht und halten sich teilweise auch nicht an die Namenskonventionen bei Python. Das ist keine Kosmetik, das ist *wichtig*.

Das erste ``import`` hat keinen sinnvollen Effekt weil der Name gleich in der nächsten Zeile wieder überschrieben wird.

Importe gehören auch nicht in Funktionen sondern an den Anfang des Moduls.

Und Funktionen gehören in aller Regel auch nicht in Funktionen/Methoden. Es gibt ein paar Ausnahmen, die sind aber selten, und ich sehe nicht, dass das hier Sinn macht.

`wa` kommt irgendwo magisch aus der ”Umgebung”. Alles was eine Funktion oder Methode ausser Konstanten benötigt, sollte als Argument(e) übergeben werden.

Das ``if wa == "auto":`` ist überflüssig, weil man an die Stelle gar nicht käme wenn diese Bedingung nicht zuträfe – das wird in der Bedingung der ``while``-Schleife ja bereits geprüft.

`time.sleep()` hat in GUI-Code nichts zu suchen. Das blockiert die GUI. Wenn man in einer GUI etwas zeitverzögert machen möchte, dann muss man mit `after()` arbeiten. Damit kann man auch länger laufende Schleifen ersetzen in dem man die Arbeit auf kurze Stückchen aufteilt die jeweils in einem Rückruf erledigt werden.

``a - b == 0`` ist eine recht komplizierte Art ``a == b`` zu schreiben.

Und wenn Du nur Stunden, Minuten, und Sekunden von `datetime`-Objekten vergleichst, könntest Du Dir auch einfach `time`-Objekte erstellen (und da gegebenenfalls die Millisekunden durch 0 ersetzen) und dann einfach die ganzen Objekte vergleichen, statt jede Komponente einzeln.

`auto_on` und `auto_off` werden *in* der Schleife auch dauernd neu erstellt – aber immer mit den gleichen Werten.

Der Code hier macht das gleiche was Deiner macht:

Code: Alles auswählen

        def baw1():
            from temp1 import temp1
            e5 = int(self.Entry2.get())
            e1 = int(self.Text1.get())
            e2 = int(self.Text2.get())
            e3 = int(self.Text1_2.get())
            e4 = int(self.Text1_3.get())

            print(e5)
            print(e4)
            print(e3)
            print(e2)
            print(e1)
            print(wa)

            if temp1 < e5 and wa == 'auto':
                auto_on = datetime.time(e1, e2)
                auto_off = datetime.time(e3, e4)
                while True:
                    now = datetime.datetime.now().time().replace(microsecond=0)
                    print(now)
                    time.sleep(1)
            
                    if now == auto_on:
                        print('On')
                        time.sleep(1)
                    elif now == auto_off:    
                        print('Off')
                        time.sleep(1)
Letztendlich will man solche Zeiten aber auch gar nicht auf Gleicheit testen. Auch wenn das Fenster hier eine ganze Sekunde ist, wäre mir das nicht robust genug. Besser ist es zu prüfen ob eine Zeitmarke überschritten ist und sich zu merken in welchem Zustand man sich gerade befindet.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Julianonl
User
Beiträge: 2
Registriert: Donnerstag 18. April 2019, 13:47

Vielen Dank blackjack,
Wie schon gesagt bin ich noch ein ziemlicher anfänger und ich habe mir das meiste auch selber beigebracht.
Deshalb war mein script auch so unübersichtlich und viel zu lang.
Benutzeravatar
__blackjack__
User
Beiträge: 14042
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Julianonl: Ich wäre übrigens eher zurückhaltend was das Steuern von Sachen angeht, von denen die Unversehrtheit von Lebewesen abhängt, einem Raspi mit einem ganz normalen Betriebssystem zu übertragen. Für so etwas will man üblicherweise etwas viel einfacheres und deutlich stabileres/zuverlässigeres verwenden. Und selbst dann musst Du als Anfänger gründlich darüber nachdenken, ob Du eventuelle Folgen von Fehlern wirklich auf Deine Kappe nehmen willst/kannst.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Antworten