代码之家  ›  专栏  ›  技术社区  ›  Mja_205

按住按钮运行电机[复制]

  •  0
  • Mja_205  · 技术社区  · 3 年前

    我试图用python做一个GUI来控制我的机器人汽车。我的问题是如何执行确定按下按钮的功能。我想在按住按钮时移动汽车,在松开按钮时停止汽车。

    from Tkinter import * 
    
    hold_down = False 
    root = Tk()
    
    def button_hold(event):
          hold_down=true
          while hold_down== True: 
                   print('test statement')
                   hold_down = root.bind('<ButtonRelease-1>',stop_motor)
    
    def stop_motor(event):
           hold_down= False
           print('button released')
    
    button = Button(root, text ="forward")
    button.pack(side=LEFT)
    root.bind('<Button-1>',button_forward)
    root.mainloop()
    

    我试图模拟我在这里面发现的东西 answer

    我试着用一种 while 使用布尔值循环。当用户按下按钮时,布尔值变为 True 代码进入while循环。当用户释放按钮时,布尔值变为 False 代码退出循环,但在这段代码中,无论我是否释放按钮,布尔值始终为真。

    Edit:我希望在条件出现之前调用一个函数。要调用的函数是hold_down(),要检查的条件是按钮被释放。

    更新:我找到了一种方法。

    0 回复  |  直到 8 年前
        1
  •  11
  •   Bryan Oakley    10 年前

    按下按钮时设置标志,松开按钮时取消设置标志。不需要循环,因为你已经在运行循环了( mainloop )

    from Tkinter import * 
    running = False
    root = Tk()
    def start_motor(event):
        global running
        running = True
        print("starting motor...")
    
    def stop_motor(event):
        global running
        print("stopping motor...")
        running = False
    
    button = Button(root, text ="forward")
    button.pack(side=LEFT)
    button.bind('<ButtonPress-1>',start_motor)
    button.bind('<ButtonRelease-1>',stop_motor)
    root.mainloop()
    

    假设您真的想在按键时做点什么,您可以使用以下命令设置动画循环 after 例如,要在按下按钮时每秒调用一次打印语句,您可以添加一个执行打印语句的函数,然后安排一秒钟后调用它自己。停止按钮只需要取消任何挂起的作业。

    这里有一个例子。与原始代码的主要区别在于添加了 move 功能。我还添加了第二个按钮,以显示如何使用相同的功能前进或后退。

    from Tkinter import * 
    running = False
    root = Tk()
    jobid = None
    
    def start_motor(direction):
        print("starting motor...(%s)" % direction)
        move(direction)
    
    def stop_motor():
        global jobid
        root.after_cancel(jobid)
        print("stopping motor...")
    
    def move(direction):
        global jobid
        print("Moving (%s)" % direction)
        jobid = root.after(1000, move, direction)
    
    for direction in ("forward", "backward"):
        button = Button(root, text=direction)
        button.pack(side=LEFT)
        button.bind('<ButtonPress-1>', lambda event, direction=direction: start_motor(direction))
        button.bind('<ButtonRelease-1>', lambda event: stop_motor())
    
    root.mainloop()
    
        2
  •  2
  •   Joseph Farah    10 年前

    你可能想试试 repeatinterval 选项。它的工作原理是,只要用户按住按钮,它就会持续发光。这个 重复间隔 参数本质上让程序知道如果是这样,它应该多久触发一次按钮。这是一个解释链接:

    http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/button.html

    在页面中搜索“repeatinterval”。

    此参数的另一个名称是 repeatdelay .

        3
  •  1
  •   Steven Summers    10 年前

    基于Bryan Oakley的回答,即使用旗帜来模拟按住按钮。问题是,在tkinter应用程序中不能有任何while循环来表示 行驶时,将汽车向前移动 .

    这就是为什么我建议使用线程。这样,你就可以在后台运行一个while循环,检查汽车是否应该向前行驶。

    from threading import Thread
    from Tkinter import *    
    
    running = False
    root = Tk()
    
    def start_motor(event):
        global running
        print("starting motor...")
        running = True
    
    def stop_motor(event):
        global running
        running = False
        print("stopping motor...")
    
    def move_forward():
        while True: # Thread will run infinitely in the background
            if running:
                print("Car is moving forward...\n")
    
    button = Button(root, text ="forward")
    button.pack(side=LEFT)
    button.bind('<ButtonPress-1>',start_motor)
    button.bind('<ButtonRelease-1>',stop_motor)
    
    # Create and start the new thread
    t = Thread(target = move_forward, args = ())
    t.start()
    
    root.mainloop()
    
        4
  •  0
  •   Danny    10 年前

    试试这个。。。

    from Tkinter import *  
    root = Tk()
    global hold_down
    
    def button_hold(event):
        hold_down = True
        while hold_down: 
            print('test statement')
    
    def stop_motor(event):
        hold_down = False
        print('button released')
    
    button = Button(root, text ="forward")
    button.pack(side=LEFT)
    root.bind('<Button-1>',button_hold)
    root.bind('<ButtonRelease-1>',stop_motor)
    root.mainloop()
    
        5
  •  -1
  •   kiri_23    10 年前

    @Danny尝试以下代码:

    def stop_motor(事件): 打印(“按钮已释放”) return假

    此答案运行打印一次“测试语句”。按下按钮时,while循环运行一次。

    @Bryan Oakley按下按钮时设置标志,松开按钮时取消设置标志。不需要循环,因为您已经在运行循环(mainloop)

    from Tkinter import * 
    running = False
    
    root = Tk()
    def start_motor(event):
        global running
        running = True
        print("starting motor...")
    
    def stop_motor(event):
        global running
        print("stopping motor...")
        running = False
    
    button = Button(root, text ="forward")
    button.pack(side=LEFT)
    root.bind('<ButtonPress-1>',start_motor)
    root.bind('<ButtonRelease-1>',stop_motor)
    root.mainloop()
    

    当按下按钮时,上述答案将保持无限循环。

    @Joseph Farah你可能想试试重复间隔选项。它的工作原理是,只要用户按住按钮,它就会持续发光。repeatinterval参数本质上让程序知道如果是这样,它应该多久触发一次按钮。下面是一个解释链接:

    http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/button.html

    在页面中搜索“repeatinterval”。

    此参数的另一个名称是repeatdelay。

    我在按钮小部件的参数选项中设置了重复间隔,但它不会重复命令。

    谢谢你的回答。仍在寻求解决这个问题。