我想切换按钮并使用 tkinter 在标签上显示其更改。
如果我按下按钮,标签上会显示“打开”,当我再次按下按钮时,标签上会显示“关闭”
所以我尝试这些代码,如果我尝试了错误的代码,请帮助我使用 tkinter 编写正确的代码。
我在组合此代码时遇到问题
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(22,GPIO.IN,up_down=GPIO.PUD_UP)
while(1):
if GPIO.input(22)==1:
if bs == False :
x.set("on")
bs=True
sleep(0.5)
else:
x.set("off")
bs=False
sleep(0.5)
这工作正常,但我想将其连接到 GUI 标签以在其上打印或关闭。
这是 tkinter 代码
import tkinter.*
root = tk()
x = StringVar()
s=Label(root,textvariable=x)
s.grid(column=0,row=0)
root.mainloop()
当我尝试组合它时,我把它做成这样
from Tkinter import *
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7,GPIO.IN)
b=False
def check_button1():
if GPIO.input(7)== 1:
if b == False :
labelText1.set("on")
print"on"
b=True
time.sleep(0.5)
else:
labelText1.set("off")
print"off"
b=False
time.sleep(0.5)
mamdouh.after(10,check_button1)
mamdouh = Tk()
labelText1 = StringVar()
x1 = Label(mamdouh,textvariable=labelText1)
x1.config(font=('Helvetica',25,'bold'))
x1.grid(row=0,column=0)
mamdouh.title("mamdouh")
mamdouh.geometry('1200x700')
mamdouh.after(10,check_button1)
mamdouh.mainloop()
但是它不起作用,实际上每次我按下按钮时它都会保持空白如果它运行良好我会放17个按钮
我认为问题在于将此 if 语句放在正确的位置并将 b 变量放在正确的位置,并且我认为此 if 语句和 tkinter 之间也存在问题,因为我尝试了这段代码,它工作完美,但它是不切换按钮,所以我想改变这一点,让我们也在这里添加此代码:
from Tkinter import *
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7,GPIO.IN)
def check_button1():
if(GPIO.input(7) == GPIO.LOW):
labelText1.set("on")
else:
labelText1.set("off")
mamdouh.after(10,check_button1)
mamdouh = Tk()
labelText1 = StringVar()
x1 = Label(mamdouh,textvariable=labelText1)
x1.config(font=('Helvetica',25,'bold'))
x1.grid(row=0,column=0)
mamdouh.title("mamdouh")
mamdouh.geometry('1200x700')
mamdouh.after(10,check_button1)
mamdouh.mainloop()
那么我如何在标签上制作这个切换按钮?
您的问题是识别按钮按下和按钮按下事件。 您的操作系统鼠标驱动程序会为您的鼠标按钮执行此操作。如果您的 GPIO 模块没有为您执行此操作,您将必须通过将当前状态与先前状态进行比较来检测这些事件。 (我在这里忽略了任何可能需要“消除弹跳”按钮的需要。)您有点尝试使用 time.sleep(.5) 调用来执行此操作,但不要在 gui 代码中使用 time.sleep 。
您的驱动程序应该是独立的,并且独立于除 .after 所需的根之外的任何 tk 小部件。 对于多个按钮,您将需要自己的 GPIOButton 类。 您的有效代码是一个起点。 Tkinter 允许您将命令与按钮事件绑定。 您的类 init 应该类似地接受向上和/或向下事件命令(回调)。
这里有一些未经测试的东西,可能可以帮助您入门。
class GPIOButton:
def __init__(self, master, buttons, command_down=None, command_up=None):
self.master = master
self.buttons = buttons
self.command_down = command_down
self.command_up = command_up
GPIO.setmode(GPIO.BOARD)
for button in buttons:
GPIO.setup(button, GPIO.IN)
self.state = [GPIO.HIGH] * len(buttons) # best initial value?
self.check_buttons() # or call this elsewhere
def check_buttons(self):
for i, button in enumerate(self.buttons):
oldstate = self.state[i]
newstate = GPIO.input(button)
if oldstate != newstate:
self.state[i] = newstate
command = (self.command_down if newstate==GPIO.LOW
else self.command_up)
command(button)
self.master.after(10, self.check_button)
让我在我的回答前加上一个免责声明——我没有 Raspberry Pi,所以无法验证这是否适用于真实的东西。为了进行测试,我使用了一个模拟随机按钮按下的代理类。您可能需要根据 GPIO 接口的工作速度来调整
DELAY
值。
但是,我已将注释掉的代码放在顶部附近,显示我认为您需要在代码中这样做的基础上使用的内容。
try:
import Tkinter as tk
import tkFont
except ImportError: # Python 3
import tkinter as tk
import tkinter.font as tkFont
#import RPi.GPIO as GPIO
#
#GPIO.setmode(GPIO.BOARD)
#
#class GPIOButton(object):
# """ Encapsulates GPIO button interface. """
# def __init__(self, pin):
# self.pin = pin
# self.status = 0
# GPIO.setup(pin, GPIO.IN)
#
# def update_status(self):
# self.status = GPIO.input(pin) == GPIO.LOW
### Proxy class since I don't have a Rasperry Pi. ###
import random
class GPIOButton(object):
def __init__(self, pin):
self.pin = pin
self.status = 0
def update_status(self):
if not random.randint(0, 99) % 20: # occassionally toggle status
self.status = not self.status
class App(tk.Frame):
STRIDE = 8
DELAY = 100 # delay in millsecs between button status updates
def __init__(self, gpio_buttons, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.gpio_buttons = gpio_buttons
self.create_widgets()
self.after(self.DELAY, self.update_buttons, self.DELAY) # start updates
def create_widgets(self):
self.btn_font = tkFont.Font(family="Helvetica", size=12, weight='bold')
self.gui_buttons = []
for i, button in enumerate(self.gpio_buttons):
is_pressed = tk.BooleanVar()
is_pressed.set(False)
radiobutton = tk.Radiobutton(self,
text=format(i+1, '02d'),
font=self.btn_font,
value=True,
variable=is_pressed,
relief=tk.RIDGE)
row, col = divmod(i, self.STRIDE)
radiobutton.grid(column=col, row=row)
self.gui_buttons.append(is_pressed)
def update_buttons(self, delay):
for i, gpio_button in enumerate(self.gpio_buttons):
previous_status = gpio_button.status
gpio_button.update_status()
if gpio_button.status != previous_status:
self.gui_buttons[i].set(gpio_button.status)
self.after(delay, self.update_buttons, delay) # rinse and repeat
gpio_buttons = [GPIOButton(pin) for pin in range(16)]
app = App(gpio_buttons)
app.master.title('Rasberry Pi Buttons')
app.mainloop()
这是在我的 Windows 计算机上运行模拟的效果: