我已经使用 tkinter 编写了一个图形用户界面,我需要将 2 个尺度的值实时发送到 arduino。我已经验证了 arduino 正在使用另一个向 arduino 发送值的草图工作,并且收到了这些值,我已将以下代码添加到我的 python 代码中
while True:
#command = raw_input("Enter level ")
#if command == '1' :
ser.write("c"+str (c1v.get()))
ser.write(":d"+str (c2v.get()))
我已经将它移到了 tkinter 主循环的内部和外部,并且从 gui 中得到了不同的结果,而不是在 gui 关闭后只发送数据。有人能告诉我如何让 gui 运行吗?当我移动比例尺时,值会通过串行实时发送到 arduino。
代码如下:
from Tkinter import *
import serial
ser = serial.Serial('/dev/ttyAMA0', 9600)
master= Tk()
master.geometry('500x500+0+0')
def print_value(val):
print ("c1="+str (c1v.get()))
print ("c2="+str(c2v.get()))
c1v=DoubleVar()
c2v=DoubleVar()
c1 = Scale(master, from_=255, to=0, length =400,width =100, troughcolor = 'blue',command=print_value, variable =c1v)
c1.grid(row=1,column=1)
c2 = Scale(master, from_=255, to=0, length =400,width =100, troughcolor = 'blue',command=print_value, variable =c2v)
c2.grid(row=1,column=2)
def load_p1():
pass
lp1 = open("/home/pi/Desktop/IEP/test/preset_test.txt")
val1, val2 = (x.split("=")[1] for x in lp1)
c1.set(val1)
c2.set(val2)
lp1.close()
#
def record():
save_path = '/home/pi/Desktop/IEP/test'
name_of_file = ("preset_test")
completeName = os.path.join(save_path, name_of_file+".txt")
file1 = open(completeName , "w")
toFile = ("c1="+str (c1.get())+ "\n""c2="+str(c2.get()))
file1.write(toFile)
file1.close()
rec=Button(master, text="Record",width=20, height=10, bg='Red', command=record)
rec.grid(row=2, column=1)
load=Button(master, text="Load",width=20, height=10, bg='gold',command=load_p1)
load.grid(row=2, column=2)
master.mainloop()
while True:
#command = raw_input("Enter level ")
#if command == '1' :
ser.write("c"+str (c1v.get()))
ser.write(":d"+str (c2v.get()))
最佳答案
上下文
您使用了 Tkinter mainloop
和一个 while
循环,现在您想将两者放在一个程序中。
while X:
do_y()
和
master.mainloop()
解决方案
有多种解决方案适合您。
拆分循环并使用
after
让 GUI 给您回电:def do_y2(): do_y() if X: master.after(123, do_y2) # after 123 milli seconds this is called again do_y2() master.mainloop()
有关更详细的答案,请参阅 this answer通过 Bryan Oakley
使用 guiLoop由我。
from guiLoop import guiLoop # https://gist.github.com/niccokunzmann/8673951#file-guiloop-py @guiLoop def do_y2(): while X: do_y() yield 0.123 # give the GUI 123 milli seconds to do everything do_y2(master) master.mainloop()
guiLoop 使用 1. 中的方法,但允许您使用一个或多个 while 循环。
使用
update
刷新 GUI。while X: do_y() master.update()
这种方法是一种不寻常的方法,因为它取代了作为大多数 GUI 框架(如 Tkinter)一部分的主循环。请注意,对于 1 和 2,您可以有多个循环,而不是像 3 中那样只有一个循环。
使用一个新的执行线程来并行执行您的循环。 !此线程不能直接访问 master 或任何 GUI 元素,因为 Tkinter 可能会崩溃!
import threading def do_y_loop(): while X: do_y() thread = threading.Thread(target = do_y_loop) thread.deamon = True # use this if your application does not close. thread.start() master.mainloop()
在新线程中启动主循环。与 4 中一样。如果您从线程访问 GUI,Tkinter 可能会崩溃。
import threading thread = threading.Thread(target = master.mainloop) thread.deamon = True # use this if your application does not close. thread.start() while X: do_y()
在 4. 和 5. 中,GUI 和 while 循环之间的通信可以/应该通过全局变量,但绝不能通过 tkinter 方法。
对于 PyQT,请参阅以下问题:
关于python - tkinter 循环和串行写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21532523/