【问题标题】:I want to toggle a real pushbutton and display it on tkinter GUI我想切换一个真正的按钮并在 tkinter GUI 上显示它
【发布时间】:2016-08-28 13:23:52
【问题描述】:

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


【解决方案1】:

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

【讨论】:

  • 其实,我理解你60%的回答,因为我没有python经验,但我在我的项目中使用它,所以你能告诉我如何使用这段代码
  • ...你能解释一下我将如何使用这段代码
  • 好吧,慢慢来。希望你能找到答案
  • 我试过这段代码,但它太慢了,有时没有响应这里是代码:pastebin.com/Zqxu0XnG
【解决方案2】:

让我先声明一下我的答案——我没有 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 计算机上运行的样子:

【讨论】:

  • mamdouh:有机会尝试一下吗?
猜你喜欢
  • 2012-11-04
  • 2020-08-24
  • 2021-06-02
  • 2018-07-23
  • 1970-01-01
  • 2014-06-02
  • 2016-08-21
  • 1970-01-01
  • 2016-01-22
相关资源
最近更新 更多