从函数设置串行对象(从 tkinter 交互调用)

Setting up the serial object from a function (called from tkinter interaction)

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

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

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

然后我的所有代码都会运行。

但问题在于所有内容都是硬编码的。 我希望用户能够从下拉列表中 select COM 端口。 当他 select 一个端口时,串行通信应该开始。

所以我就是这样建造的。这是我的相关代码。

#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)

当我从下拉列表中 select 一个 COM 端口时,会发生什么情况?我在设备的 LED 按钮上看到传输。

但是,文本框上没有显示任何内容。之前,当我对所有内容进行硬编码并在程序开头设置 serialobject,并在程序结尾处调用 readSerial() 函数时,一切正常。

在您的 on_select 函数中,您在调用 readSerial() 函数之前调用了 returnreturn 语句终止函数的执行,它后面的任何语句都不会执行。删除它将使程序运行。

此外,由于 on_select 是下拉列表的回调,因此 return 语句是多余的,因为它没有 return 的任何地方。 global ser 负责将新值全局分配给 ser 变量。

不需要每次选择新选项都调用readSerial()函数(否则每次都会增加预定调用的次数)。您可以有一个按钮,一旦您最初配置它并删除对 readSerial() 形式的调用 on_select 或创建一个标志以确保它只被调用一次。


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

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()