我想切换一个真正的按钮,并显示在tkinter图形用户界面上

2024-10-02 10:19:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用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代码

^{pr2}$

当我试着把它组合成这样

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 statment放在正确的地方,把b变量放在它的正确位置,我认为这个if statment和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()

那么我怎样才能在标签上做这个切换按钮呢?在


Tags: 代码importfalsegpioiftimetkintercheck
2条回答

让我用一个免责声明作为我的回答的开头——我没有覆盆子派,所以不能用真实的东西来验证这一点。为了进行测试,我使用了一个代理类来模拟随机按下按钮。您可能需要根据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

您的问题是识别按钮向下和按钮向上事件。您的操作系统鼠标驱动程序为您的鼠标按钮执行此操作。如果GPIO模块没有为您执行此操作,则必须通过比较当前状态与以前的状态来检测这些事件。(我在这里忽略了任何可能需要“去弹跳”按钮的情况。)您正在尝试使用时间。睡觉(5)调用,但不使用时间。睡觉在gui代码中。在

您的驱动程序应该是自包含的,并且独立于除.after所需的根之外的任何tk小部件。你需要多个按钮,你需要自己的类。你的代码是一个起点。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)

相关问题 更多 >

    热门问题