在Python中打开,显示和关闭串口

时间:2015-01-14 05:18:04

标签: python-3.x text tkinter pyserial

我想创建一个可以打开串口的gui,在文本小部件中显示接收的值并关闭它。打开串口已完成,但我找不到在文本小部件中显示接收值的方法。此外,当我点击打开按钮时,gui没有响应。那是因为while循环用于显示串口数据。我认为必须有串口数据接收事件,但我对它一无所知。如何在文本框中显示串口数据,并在打开端口后使其他按钮响应。

from tkinter import *
import serial

root = None

class serial_window(Frame):
    ser = serial.Serial()
    #open = 0

    def serial_open(self):
        if (serial_window.ser.isOpen() == 0):
            serial_window.ser.baudrate = 9600
            serial_window.ser.port = 4-1
            serial_window.ser.open()

                self.after_idle(self.writeline)  #while True:
                print(serial_window.ser.readline())

    def serial_close(self):
        if (serial_window.ser.isOpen() == 1):
            serial_window.ser.close()

    def open(self):
        self.OPEN = Button(self, text = "OPEN", fg = "blue", command = self.serial_open)
        #self.OPEN["command"] = self.open_port
        self.OPEN.grid(row = 0, column = 0)

    def close(self):
        self.CLOSE = Button(self, text = "CLOSE", fg = "blue", command = self.serial_close)
        #self.OPEN["command"] = self.open_port
        self.CLOSE.grid(row = 0, column = 1)

    def exit_main(self):
        self.exit_main = Button(self, text = "EXIT", fg = "red", command = self.quit)
        self.exit_main.grid(row = 0, column = 2)

    def console(self):
        self.console = Text(self, fg = "red")
        self.console.grid(row = 1, column = 0, columnspan = 3)

    def writeline(self, event):
            self.console.insert('insert', serial_window.ser.readline())
            if serial_window.ser.isOpen():
                self.after_idle(self.writeline)

    def createWidgets(self):
        self.open()
        self.close()
        self.exit_main()
        self.console()

    def __init__(self, master = None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()


root = Tk()
app = serial_window(master = root)
app.mainloop()
root.destroy()

从串口连续接收的数据是 - '监控\ r \ n'

1 个答案:

答案 0 :(得分:0)

我建议将ser作为实例而不是类变量。它将使代码更紧凑,甚至更快。但回答代码是......

您可以使用重复的回调方法(例如

)写入“文本”小部件
def writeline(self, event):
    self.console.insert('insert', serial_window.ser.readline())
    if serial_window.ser.isOpen():
        self.after_idle(self.writeline)  # or self.after(1, self.writeline)

将serial_open中的当前while True:替换为回调中最后一行的副本,以启动回调循环。 readline调用仍将阻止等待完整行,但在回调返回后将处理其他事件。

我不知道串行模块使用了多大的字符缓冲区,或者它是如何与字符源握手的。如果其他事件延迟下一次调用writeline,则字符可能会丢失。