2017-05-05 3 views
0

Ich versuche gerade ein Sicherheitssystem auf meinem Raspberry Pi zu bauen. Ich habe 9 Tasten, um einen Code einzugeben. Sobald der Code eingegeben ist, können Sie "Arm" drücken, um das System scharf zu schalten. Dann prüft eine Funktion einen PIR-Sensor auf Bewegung. Wenn Bewegung erkannt wird, sollte ein Alarm ausgelöst werden, für den ich Zeit brauche. Also ist mein aktuelles Problem, mit time.sleep blockiere ich das Programm für die Zeit, die es schläft, also kann ich das System im Alarmmodus nicht unscharf schalten.Erstellen von Threads für GUI und Buttons

Meine Idee war bisher, nur alles in Threads zu setzen. Aber bisher ohne Erfolg. Gibt es bessere Lösungen für time.sleep?

+0

Prüft der PIR-Sensor etwas, das blockiert, oder dauert es lange? Oder ist es möglich, alle paar Sekunden abzufragen? –

+0

Das PIR blockiert nicht. Wenn der Alarm ausgelöst wird, ertönt alle zwei Sekunden ein Summer. Daher muss ich den Summer auf HIGH stellen, dann 2 Sekunden schlafen und dann den Summer auf LOW stellen, und so weiter. – Kev

+1

Zeigen Sie uns einen Code – gipsy

Antwort

1

Sie müssen keine Threads verwenden. Mit tkinter können Sie einfach eine Funktion planen, die alle paar Sekunden im Hauptthread ausgeführt wird, um den Sensor zu überprüfen oder andere Arbeiten auszuführen.

Hier ist ein kurzes Beispiel, das gut funktioniert, wenn man davon ausgeht, dass die Sensorprüfung nicht mehr als ein paar hundert Millisekunden dauert. Es ist nicht genau, wie ich es tun würde, aber es veranschaulicht, wie Sie eine Funktion regelmäßig ausführen lassen können, ohne die Benutzeroberfläche in den Ruhezustand versetzen zu müssen.

import tkinter as tk 

class App(): 
    def __init__(self): 
     self._job_id = None 
     self.init_gui() 

    def init_gui(self): 
     self.root = tk.Tk() 
     self.button = tk.Button(self.root, width=6, text="Arm", command=self.arm) 
     self.button.pack(padx=20, pady=20) 

    def start(self): 
     self.root.mainloop() 

    def arm(self): 
     self.button.configure(text="Disarm", command=self.disarm) 
     self.poll() 

    def disarm(self): 
     self.button.configure(text="Arm", command=self.arm) 

     if self._job_id: 
      self.root.after_cancel(self._job_id) 

    def poll(self): 
     # ... check the sensor here ... 
     movement = True 

     if movement: 
      print("beep!") 

     self._job_id = self.root.after(2000, self.poll) 
app = App() 
app.start() 
0

Wenn Ihr Problem einfach für eine bessere Methode sucht, dann time.sleep zu verwenden, könnten Sie time.time anstatt time.sleep und prüft dann prüfen, mit, um zu sehen, welche Aktionen auftreten sollten. Dies würde die Verwendung von time.sleep vermeiden, die alle Ereignisse (einschließlich Ihrer GUI) blockiert. Als schnell geschrieben Beispiel diese Idee zu demonstrieren:

from time import time 

millis = lambda: int(time() * 1000) 

def updateAlarm(lastTime, beepRate, currentState): 
    now = millis() 
    if now > (lastTime + beepRate): 
     return (not(currentState), now) 
    return (currentState, now) 


last = millis() #set the first time for the alarm 
rate = 2000 # change state every two seconds 
state = False # the alarm is currently off 

while True: # just for demonstration purposes, while True: won't work inside of a tkinter GUI 
    change = updateAlarm(last, rate, state) 
    if change[0] != state: # if the state has changed, update it and print 
     state = change[0] 
     last = change[1] 
     print(state) 

auf Ihrer Implementierung Abhängig kann dies mehr Sinn machen, vor allem wenn Sie nicht tkinter verwenden. Ich persönlich finde, Bryan's Lösung ist viel eleganter, vor allem, weil es nicht ständig überprüft werden muss, ob der Alarm aktualisiert werden muss.