tkinter 循环和串行写入 [英] tkinter loop and serial write

查看:19
本文介绍了tkinter 循环和串行写入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用 tkinter 编写了一个 gui,我需要将 2 个比例的值实时发送到 arduino.我已经验证 arduino 正在使用另一个草图工作,该草图将值发送到 arduino 并收到这些值,我已将以下代码添加到我的 python 代码中

i have written a gui using tkinter and i need to send the values of the 2 scales in realtime to an arduino. i have verified that the arduino is working using another sketch which sends values to the arduino and these are received, i have added in the following code to my python code

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.

i have moved this inside and outside of the tkinter mainloop and get varied results from the gui not loading to the data only sending once the gui is closed. can someone tell me how to get the gui to run and as i move a scale the value is sent to the arduino in real time over serial.

代码如下:

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())+ "
""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 循环,现在您想将两者放在一个程序中.

You use the Tkinter mainloop and a while-loop and now you want to put both together into one program.

while X:
    do_y()

master.mainloop()

解决方案

有多种解决方案适合您.

There are several solutions for you.

  1. 分割循环并使用 after 让 GUI 给你回电:

  1. split the loop and use after to let the GUI call you back:

def do_y2():
    do_y()
    if X:
        master.after(123, do_y2) # after 123 milli seconds this is called again
do_y2()
master.mainloop()

有关更详细的答案,请参阅 此答案/7432/bryan-oakley">布莱恩奥克利

For a more detailed answer see this answer by 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 循环.

guiLoop uses the approach from 1. but allows you to use one or more while loops.

使用 update 刷新 GUI.

use update to refresh the GUI.

while X:
    do_y()
    master.update()

这种方法是一种不寻常的方法,因为它取代了大多数 GUI 框架(如 Tkinter)中的主循环.请注意,对于 1 和 2,您可以有多个循环,而不是 3 中的一个.

This approach is an unusual one since it replaces the mainloop that is part os the most GUI frameworks like Tkinter. Note that with 1 and 2 you can have multiple loops, not just one as in 3.

使用新的执行线程并行执行您的循环.!该线程不能直接访问 master 或任何 GUI 元素,因为那样 Tkinter 可能会崩溃!

use a new thread of execution that executes your loop in parallel. ! This thread must not access master or any GUI elements directly because Tkinter can crash then!

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 可能会崩溃.

  • start the mainloop in a new thread. As in 4. Tkinter can crash if you access the GUI from the thread.

    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 方法.

    In both 4. and 5. communication between the GUI and the while-loop could/should go through global variables but never through tkinter methods.

    <小时>

    对于 PyQT,请参阅以下问题:


    For PyQT see these questions:

    这篇关于tkinter 循环和串行写入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆