小编典典

tkinter循环和串行写入

python

我已经使用tkinter编写了gui,我需要将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
mainloop的内部和外部移动了它,并且从gui获得了不同的结果,而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()))

阅读 193

收藏
2020-12-20

共1个答案

小编典典

语境

您使用了Tkintermainloopwhile-loop,现在您想将它们放到一个程序中。

while X:
    do_y()

master.mainloop()

解决方案

有几种适合您的解决方案。

  1. 分割循环,并使用它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()

  2. 由我使用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循环。

  1. 用于update刷新GUI。
    while X:
    do_y()
    master.update()
    

这种方法是一种不寻常的方法,因为它取代了大多数GUI框架(例如Tkinter)中的mainloop。请注意,使用1和2可以有多个循环,而不仅仅是3中的一个。

  1. 使用新的执行线程来并行执行循环。!该线程不得直接访问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()

  2. 在新线程中启动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方法进行。


2020-12-20