我正在使用Tkinter窗口将信息通过串口传递给arduino,这会使步进电机转动一定数量的步骤。基本上我有按钮,对应于我想要电机采取的步数。当我按下按钮时,我希望电机移动那么多步。生病了我的代码的一些片段但是基本上我的问题是窗口在第一次按下按钮时效果很好但是当我点击其他按钮让电机继续移动时我什么也得不到。几乎看起来Tkinter窗口只能单击一下或卡在回调函数中。
回调函数:
def firstGrating():
arduino.write('1800')
tkMessageBox.showwarning(title= 'Spectrometer', message = 'I am moving to the 1800 Grating...')
tkMessageBox.showwarning(title= 'Spectrometer', message = 'Please Wait Until I Tell You That I AM FINISHED!!!')
while True:
message = arduino.readline()
if len(message) > 10:
tkMessageBox.showwarning(title= 'Spectrometer', message = message)
return
def secondGrating():
arduino.write('150')
tkMessageBox.showwarning(title= 'Spectrometer', message = 'I am moving to the 150 Grating...')
tkMessageBox.showwarning(title= 'Spectrometer', message = 'Please Wait Until I Tell You That I AM FINISHED!!!')
while True:
message = arduino.readline()
if len(message) > 10:
tkMessageBox.showwarning(title= 'Spectrometer', message = message)
return
def thirdGrating():
arduino.write('3600')
tkMessageBox.showwarning(title= 'Spectrometer', message = 'I am moving to the 3600 Grating...')
tkMessageBox.showwarning(title= 'Spectrometer', message = 'Please Wait Until I Tell You That I AM FINISHED!!!')
while True:
message = arduino.readline()
if len(message) > 10:
tkMessageBox.showwarning(title= 'Spectrometer', message = message)
return
这是我尝试设置我的Tkinter窗口的部分:
win = Tk()
win.geometry("600x400+500+500")
win.title('Spectrometer Controller')
mlabel = Label(text = 'Select One of The Available Gratings')
mlabel.pack()
mButton1 = Button(win, text = '1800', command = lambda: firstGrating())
mButton1.pack()#.grid(row=0, column=1)
mButton2 = Button(win, text = '150', command = lambda: secondGrating())
mButton2.pack()#.grid(row=0, column=2)
mButton3 = Button(win, text = '3600', command = lambda: thirdGrating())
mButton3.pack()#.grid(row=0, column=3)
win.mainloop()
答案 0 :(得分:1)
你是对的,它会陷入回调中。 Tkinter
mainloop()
与while
循环产生冲突并变得无法响应,因此在while
循环时无法按下其他按钮正在运行。
您可以查看after()
方法来创建一个程序化循环,以保持您的GUI响应。这是一个例子:
def callback(flag):
global loop
if flag is True:
print('message')
... other logic ...
# start the after method to call the callback every 100ms
loop = root.after(100, callback, True)
else:
# cancel the after method if the flag is False
root.after_cancel(loop)
root = Tk()
# use a lambda expression to pass arg to callback in button commands
Button(root, text='start', command=lambda: callback(True)).pack()
Button(root, text='stop', command=lambda: callback(False)).pack()
mainloop()
您还可以将GUI和业务保持在单独的线程中,但这通常是要设置的PITA。 after()
方法通常同样有效。