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

查看:248
本文介绍了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关闭时才将其不加载到数据中.有人可以告诉我如何运行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())+ "\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 mainloopwhile循环,现在您希望将两者组合到一个程序中.

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回叫您

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.

while X:
    do_y()
    master.update()

这种方法是一种不寻常的方法,因为它取代了大多数GUI框架(如Tkinter)中的mainloop.请注意,使用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:

    • How to quit the program in while loop using push-button in PyQt
    • How to set push-button to keyboard interrupt in PyQt

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

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