Kivy Oberfläche während Funktionsaufruf freigeben

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Dudu
User
Beiträge: 13
Registriert: Donnerstag 13. April 2017, 08:30

Mittwoch 3. Mai 2017, 13:00

Hallo,

momentan versuche ich eine Schrittmotorsteuerung für das Raspi-Touchpanel mit Kivy zu schreiben.
Das Problem auf dass ich momentan gestoßen bin ist dass wenn ich per Buttonklick eine Funktion aufrufen möchte
friert die Oberfläche solange ein bis die Funktion abgearbeitet ist. Da es sich bei einer der Funktionen um einen
Dauerbetrieb handelt der mit einem zweiten Button gestoppt werden soll muss ich dies umgehen. Ich habe es schon
über Threads versucht allerdings wartet Kivy dann trotzdem auf den Abschluss des Threads. Vielen Dank bereits im
vorraus für die Hilfe.

Mit vielen Grüßen,

Euer Dudu

Code: Alles auswählen

        BoxLayout:
    
            spacing: 10
            padding: 5
            size_hint_x: 0.5
            Button:
                text: "Quickstart"
                on_release:
                    root.manager.transition.direction = 'left'
                    root.manager.transition.duration = 0.5
                    root.manager.current = 'screen_two'
                    root.Dauerbetrieb()
                    
                    
class ScreenOne(Screen):
    
    def Dauerbetrieb (self):
            GPIO.setup(18, GPIO.OUT)
            GPIO.setup(24, GPIO.OUT)
            iDelay = 5
            Beschleunigungs_Rampe = 3* iDelay
            global escaper
            escaper = 0
            while escaper == 0 :

                
                if Beschleunigungs_Rampe > iDelay:
                    GPIO.output(24, GPIO.HIGH)
                    time.sleep((Beschleunigungs_Rampe / 1000.0))
                    print (1)
                    GPIO.output(24, GPIO.LOW)

                    # Hier kann Koeffizient zur Steilheit der Rampe geändert werden
                    # Desto kleiner der Subtrahent desto langsamer die Beschleunigung
                    Beschleunigungs_Rampe = Beschleunigungs_Rampe - 0.01

                else:

                    GPIO.output(24, GPIO.HIGH)
                    time.sleep((iDelay / 1000.0))
                    GPIO.output(24, GPIO.LOW)
                    print (1)
    t1= Thread(target=Quickstart, args=())
    t2= Thread(target=Quickstart, args=())

    t1.start()
    t2.start()
__deets__
User
Beiträge: 3332
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mittwoch 3. Mai 2017, 13:57

Es bringt nichts einfach irgendwo irgendwelche Threads zu starten, aber in der Ereignisbehandlung dann einfach das zu machen, was man vorher auch gemacht hat. Was soll da passieren? Da wird doch nicht magisch ploetzlich paralleler Code draus.

Du musst *IN* Dauerbetrieb einen neuen Thread starten, bzw noch besser einen globalen Kontrollthread starten & dann in Dauerbetrieb ueber eine Queue Kommandos verschicken

Code: Alles auswählen

import time
import threading
import random
import Queue

STOP, FORWARD, BACKWARD = xrange(3)

def controller(q):
    status = STOP
    while True:
        try:
            status = q.get(timeout=.1)
        except Queue.Empty:
            pass
        if status == STOP:
            print("stop")
        elif status == FORWARD:
            print("forward")
        elif status == BACKWARD:
            print("backward")



def main():
    command_queue= Queue.Queue()
    t = threading.Thread(target=controller, args=(command_queue,))
    t.daemon = True
    t.start()
    while True:
        time.sleep(1.0)
        # das hier muss in Dauerbetrieb, am besten *OHNE* globale
        # variable command_queue, wie auch immer man das in Kivy
        # hinbekommt.
        command_queue.put(random.choice([STOP, FORWARD, BACKWARD]))

if __name__ == '__main__':
    main()

Antworten