0

所以,我一直在研究连接到我的树莓派 4 的 LED 灯条,并且我已经让 TouchOSC 在树莓派和我的手机之间工作。我目前遇到的问题是,当我按下的切换按钮关闭时,它指定运行的程序继续运行。我有一个全局变量,它应该确定“while”循环是否继续,但不是将按钮状态设置为零并终止程序,而是继续运行,直到它被终端中的 Ctrl+C 中断。我想知道是否有人会碰巧知道为什么当按钮状态改变时程序不会停止。

def twinkleBtn(path, tags, args, source):
    global twinkleState
    twinkleState = int(args[0])
    if twinkleState:
       turnOff(strip)
       while twinkleState:
            twinkleTest(strip, False, 10)
    if not twinkleState:
       turnOff(strip)

这在按下闪烁按钮时触发,但当我将其切换回零时程序继续运行。下面是函数“twinkleTest”的代码

def twinkleTest(strip, onlyOne, count, wait_ms=50):
    setPixels(Color(0, 0, 0))
    for i in range(count):
        strip.setPixelColor(randint(0,LED_COUNT), Color(170, 180, 30))
        strip.show()
        time.sleep(wait_ms/250.0)
        if (onlyOne):
           setPixels(Color(0,0,0))
    time.sleep(wait_ms/500.0)

我不确定我是否只是一无所知,或者这里到底做错了什么。我对 Python 很陌生,所以它可能不是最好的。谢谢你的帮助!

4

1 回答 1

0

这是一个简单的线程解决方案。一个线程等待一个threading.Event. twinkleTest每当设置事件时调用。GUI 设置事件,闪烁将在后台发生,直到第二次按下按钮停止闪烁。

import threading

def twinkleTest(strip, onlyOne, count, wait_ms=50):
    setPixels(Color(0, 0, 0))
    for i in range(count):
        strip.setPixelColor(randint(0,LED_COUNT), Color(170, 180, 30))
        strip.show()
        time.sleep(wait_ms/250.0)
        if (onlyOne):
        setPixels(Color(0,0,0))
    time.sleep(wait_ms/500.0)

def twinkler(twinkleEvent):
    """Call twinkleTest whenever the given twinkleEvent event is set
    and keeps calling until the event is cleared. Designed to be used in
    a separate thread."""
    while True:
        twinkleEvent.wait()
        twinkleTest(strip, False, 10)

def setup_twinkle_daemon_thread():
    """Creates a daemon thread to twinkle screen whenever an event is set.
    Returns event, threadhandle"""
    twinkleEvent = threading.Event()
    twinkleThread = threading.Thread(target=twinker, args=tuple(twinkleEvent))
    twinkleThread.daemon = True
    twinkleThread.start()
    return twinkleEvent, twinkleThread

# controls twinkler
twinkleEvent = twinkleThread = None

def twinkleBtn(path, tags, args, source):
    global twinkleEvent, twinkleThread
    if twinkleEvent is None:
        # start daemon thread on first use
        twinkleEvent, twinkleThread = setup_twinkle_daemon_thread()
    if twinkleEvent.is_set():
        twinkleEvent.clear()
    else:
        twinkleEvent.set()
于 2020-07-05T18:15:35.390 回答