[LED,当不按下按钮时闪烁,并在按下按钮时持续点亮(Python)

问题描述 投票:0回答:2

所以,我有一个由Raspy控制的LED,还有一个只有一个按钮的基本GUI,我希望它的行为如下:

  • 未按下按钮时,LED闪烁。
  • 按下按钮后,LED指示灯应持续保持点亮状态。

当我执行灯时,指示灯开始闪烁,但是按钮不显示。当我中断程序时,按钮出现。为什么?

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

GPIO.setmode(GPIO.BOARD)
GPIO.setup(8, GPIO.OUT)
GPIO.output(8, False)
buttonPressed = False

master = Tk()

def callback():
    GPIO.output(8, True)
    buttonPressed = True

w = Button(master, text="Turn on light", command = callback)
w.pack()

while True:
    if buttonPressed == False:
        GPIO.output(8, True)
        time.sleep(0.5)
        GPIO.output(8, False)
        time.sleep(0.5)
    else:
        GPIO.output(8, True)
python button tkinter light
2个回答
1
投票

我认为@furas为您设定了正确的方向,但是由于我一直在努力工作,所以我想我也将解决方案留在这里。我拔出了GPIO代码,以便可以在本地运行它。

两种解决方案的一个关键功能是,我们已经删除了对time.sleep的调用,因为在您进行time.sleep处理时,Tk的事件循环无法处理任何事件(这将在UI出现时显示在这些睡眠陈述中“冻结”。

import time
import tkinter

buttonpressed = False
lastchange = 0
ledstate = False

def button_down(event):
    global buttonpressed
    print('BUTTON DOWN')
    buttonpressed = True


def button_up(event):
    global buttonpressed
    print('BUTTON UP')
    buttonpressed = False


def myloop(master):
    global buttonpressed
    global lastchange
    global ledstate

    now = time.time()
    delta = now - lastchange

    if not buttonpressed:
        if now - lastchange > 0.5:
            ledstate = not ledstate
            print('LED', ledstate)
            lastchange = now
    else:
        if not ledstate:
            ledstate = True
            print('LED', ledstate)

    master.after_idle(myloop, master)


master = tkinter.Tk()
w = tkinter.Button(master, text="Turn on light")
w.bind('<ButtonPress>', button_down)
w.bind('<ButtonRelease>', button_up)
w.pack()

master.after(100, myloop, master)
master.mainloop()

0
投票

我无法在RPi上对其进行测试,但我可能是这样的人。

[Normal command=只有在您单击按钮时才能识别,但在释放按钮时却无法识别-您需要绑定事件<ButtonPress><ButtonRelease>,这将在"mouse left button press""mouse left button release"上运行功能

我使用after()延迟运行功能,因此我不需要sleep()while可以阻止mainloop()(并且可以冻结所有GUI)。

而且我也不需要while循环,因为我在on_presson_release内全部运行,后来after()运行了turn_off_led,后者使用after()来运行turn_on_led,后者使用after()来运行再次运行turn_off_led,所以它像循环一样工作。

import tkinter as tk  # PEP8: `import *` is not preferred
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(8, GPIO.OUT)
GPIO.output(8, False)

button_pressed = False  # PEP8: preferred `lower_case_names`

# --- functions ---

def on_press(event):
    global button_pressed

    button_pressed = True
    GPIO.output(8, True)

def on_release(event):
    global button_pressed

    button_pressed = False
    GPIO.output(8, True)

    # run after 500ms (0.5s) instead of `sleep`
    master.after(500, blink_off)

def blink_off():
    if not button_pressed:
        GPIO.output(8, False)
        # run after 500ms (0.5s) instead of `sleep`
        master.after(500, blink_on)

def blink_on():
    if not button_pressed:
        GPIO.output(8, True)
        # run after 500ms (0.5s) instead of `sleep`
        master.after(500, blink_off)

# --- main ---

master = tk.Tk()

button = tk.Button(master, text="Turn on light")
button.pack()

# here "button" means "tk.Button" and "Button" means "mouse left button"
button.bind('<ButtonPress>',   on_press)   # mouse left button pressed on tk.Button 
button.bind('<ButtonRelease>', on_release) # mouse left button released on tk.Button

# start blinking - it will use `after()` to loop
blink_on()

master.mainloop()
© www.soinside.com 2019 - 2024. All rights reserved.