如何在运行另一个tk.button函数时检查按钮的按下?

3
我目前正在使用tkinter为实验室的倾斜台创建GUI。我编写了向上和向下按钮来控制针脚的开关,直到倾斜角度达到预设值(从一个通过Arduino连接的测斜仪中读取),然后关闭针脚。因此,与每个按钮相关联的函数会重复读取角度(直到达到正确的角度),但我还想在需要时关闭针脚。问题在于,当Up按钮相关的函数运行时,程序不会检查任何按钮按下事件。我该如何使暂停按钮打断函数?
我尝试使用线程库实现中断,但似乎当一个button()函数正在运行时,tkinter不允许其他代码运行。
import tkinter as tk
from tkinter import *
import RPi.GPIO as GPIO
import time
import serial
global read_serial

win = Tk()

def Up():
     if read_serial < target: 
          global read_serial  #read_serial is edited elsewhere not included here
          GPIO.output(40,GPIO.HIGH)
          time.sleep(.05)
          read_serial=ser.readline().rstrtip().decode("utf-8")
          read_serial=float(read_serial)
          Up()
     else:
          GPIO.otuput(40,GPIO.LOW)

def Pause():
     GPIO.output(40,GPIO.LOW)

upButton = Button(win,text='UP',command=Up)
pauseButton = Button(win,text='PAUSE',command=Pause)
upButton.grid(row=1)
pauseButton.grid(row=2)

win.mainloop()

我不想贴太多的代码,但如果我漏了任何关键部分,我可以包括更多内容。我希望在按暂停时中断Up(),但一旦我按下Up,程序会忽略任何输入,直到read_serial大于目标值。是否可能实现一个中断,以检查tkinter中的其他按钮按下?


@BlackThunder Thread(target=?) 我的目标是 Pause 还是 pauseButton? - BenS
2
多线程并不是唯一的解决方案,但如果GUI要保持响应,则必须相当快地从按钮命令中返回。任何正在进行的活动都可以在一个线程中执行,或者在稍后通过.after()调度的函数中逐个完成(如果活动仍未完成,则可以使用.after()重新安排自己)。 - jasonharper
@jasonharper 这可能是一个愚蠢的问题,但 .after() 必须在主循环中,对吗?这样它就可以从按钮命令返回,但如果必要,仍然可以回调到它。 - BenS
BenS: 我认为你会发现等待线程完成时Tkinter GUI冻结/挂起很有帮助。 - martineau
2
你可以直接使用 win.after(0, Up) 而不是直接调用 Up() - tobias_k
显示剩余4条评论
1个回答

1
使用tkinter运行后台函数最简单的方法是使用.after()方法,这样就不需要使用线程模块。在.after()中的0是等待执行给定函数的毫秒数。
示例(不是最好的方式,因为它现在有另一个函数):
def bnt_up():
    win.after(0, Up)
upButton = Button(win,text='UP',command=bnt_up)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接