从函数设置串行对象(从 tkinter 交互调用) [英] Setting up the serial object from a function (called from tkinter interaction)

查看:45
本文介绍了从函数设置串行对象(从 tkinter 交互调用)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设法让我的 tkinter 应用程序在文本字段上显示文本.

I managed to get my tkinter aplication to display text on a text field.

我通过硬编码 COM 端口和波特率来做到这一点,然后在我的程序开始时设置一个串行对象.

I did this by hardcoding the COM port and baud rate, then set up a serial object at the beginning of my program.

baudRate = 9600
ser = serial.Serial('COM16', baudRate)

然后我所有的代码都会在之后运行.

Then all my code runs afterwards.

但问题是一切都是硬编码的.我希望用户能够从下拉列表中选择 COM 端口.当他选择一个端口时,应该开始串行通信.

But the problem with this is that everything is hardcoded. I want the user to be able to select the COM port from a dropdown. And when he selects one port, the serial communication should start.

所以我就是这样构建的.这是我的相关代码.

So i built exactly that. Here is my relevant code.

#hardcoded baud rate
baudRate = 9600

# this is the global variable that will hold the serial object value
ser = 0 #initial  value. will change at 'on_select()'

#this function populates the dropdown on frame1, with all the serial ports of the system
def serial_ports():    
    return serial.tools.list_ports.comports()

#when the user selects one serial port from the dropdown, this function will execute
def on_select(event=None):
    global ser
    COMPort = cb.get()
    string_separator = "-"
    COMPort = COMPort.split(string_separator, 1)[0] #remove everything after '-' character
    COMPort = COMPort[:-1] #remove last character of the string (which is a space)
    ser = serial.Serial(port = COMPort, baudrate=9600)
    return ser
    readSerial() #start reading

#this function reads the incoming data and inserts them into a text frame
def readSerial():
    ser_bytes = ser.readline()
    ser_bytes = ser_bytes.decode("utf-8")
    text.insert("end", ser_bytes)
    if vsb.get()[1]==1.0:
       text.see("end")
    root.after(100, readSerial)

当我从下拉列表中选择一个 COM 端口时会发生什么,我看到我设备的 LED 按钮上的传输.

What happens when i select a COM port from the dropdown, is that i see transmision on the led buttons of my device.

但是,文本框上没有显示任何内容.之前,当我在程序开始时对所有内容进行硬编码并设置串行对象,并在程序结束时声明 readSerial() 函数时,一切正常.

However, nothing is displayed on the text frame. Before, when i hardcoded everything and setup the serialobject in the beginning of the program, and i statre the readSerial() function in the end of my program, everything worked.

推荐答案

在您的 on_select 函数中,您在调用 readSerial()<之前调用了 return/代码> 功能.return 语句终止函数的执行,它后面的任何语句都不会被执行.删除它会使程序运行.

In your on_select function, you have called return before calling the readSerial() function. The return statement terminates the execution of a function, any statements following it will not be executed. Removing it would make the program work.

另外,由于 on_select 是下拉菜单的回调,return 语句是多余的,因为它没有任何地方可以返回.global ser 负责将新值全局分配给 ser 变量.

Also, since on_select is a callback form the dropdown, the return statement is redundant as it does not have anywhere to return to. The global ser takes care of assigning the new value to the ser variable globally.

您不需要每次选择新选项时都调用 readSerial() 函数(否则每次都会增加计划调用的次数).您可以有一个按钮在您最初配置它后调用它并删除对 readSerial() 表单 on_select 的调用,或者创建一个标志以确保它已被调用只有一次.

You do not need to call the readSerial() function every time a new option is selected (else, it will increase the number of scheduled calls every time). You can either have a button that calls it once you have initially configured it and remove the call to readSerial() form on_select or create a flag that ensures that it has been called only once.

根据您的评论,我创建了以下示例,您可以尝试这样的操作

Based on your comment, I've created the following example, you could try something like this

from tkinter import *

def on_select(event):
    global value
    value=option.get()
    if stop_:
        start_button['state']='normal'

def start():
    global stop_
    stop_=False
    readSerial()
    start_button['state']='disabled'
    stop_button['state']='normal'

def stop():
    global stop_
    stop_=True
    root.after_cancel(after_id)
    start_button['state']='normal'
    stop_button['state']='disabled'

def readSerial():
    global after_id
    text.insert(END,value)
    after_id=root.after(100,readSerial)

root=Tk()

text=Text(root)
text.pack(side='bottom')

options=['1','2']
option=StringVar()
om=OptionMenu(root,option,*options,command=on_select)
om.pack(side='left')

start_button=Button(root,text='start',command=start,state='disabled')
start_button.pack(side='left')
stop_button=Button(root,text='stop',command=stop,state='disabled')
stop_button.pack(side='left')

stop_=True

root.mainloop()

这篇关于从函数设置串行对象(从 tkinter 交互调用)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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