我想切换一个真正的按钮并将其显示在 tkinter GUI 上

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

我想切换按钮并使用 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()

那么我如何在标签上制作这个切换按钮?

python python-2.7 tkinter raspberry-pi raspberry-pi2
2个回答
0
投票

您的问题是识别按钮按下和按钮按下事件。 您的操作系统鼠标驱动程序会为您的鼠标按钮执行此操作。如果您的 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)

0
投票

让我在我的回答前加上一个免责声明——我没有 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 计算机上运行模拟的效果:

screenshot of display showing the status of all sixteen buttons

© www.soinside.com 2019 - 2024. All rights reserved.