Python tkinter serial


Python tkinter serial

 

 源码是在https://blog.csdn.net/chencaw/article/details/105782159/链接的基础上改的,修改了一些bug,优化了串口接收数据

import serial
import serial.tools.list_ports
import time
import threading
from tkinter import *
from tkinter.ttk import *

 
DATA = ""         # 读取的数据
NOEND = True     # 是否读取结束
 
 
class cbh_Serial():
    def __init__(self):
        self.ser = serial.Serial()
        self.showinterface()
 
    def on_closing(self):
        global    NOEND
        NOEND=False
        if self.ser.isOpen():
            self.thread.join()
            self.ser.close()
        self.root.destroy()
 
    # 读数据的本体
    def read_data(self,ser):
        global DATA, NOEND
        while NOEND:
            if self.ser.in_waiting :
                time.sleep(0.01)
                DATA = self.ser.read(self.ser.in_waiting).decode()
                #print(DATA)
                self.recv.insert(END, DATA)

    def open_seri(self,portx, bps, timeout):
        global NOEND
        ret = False
        try:
            self.ser = serial.Serial(portx, bps, timeout=timeout)
            # 判断是否成功打开
            if self.ser.isOpen():
                ret = True
                # 创建一个子线程去等待读数据
                self.thread = threading.Thread(target=self.read_data, args=(self.ser,))
                # read_data函数中会使用NOEND做判断
                NOEND = True
                self.thread.start()
        except Exception as e:
            print("error!", e) 
        return self.ser, ret
 
 
    def btn_hit(self):
        global NOEND
        if self.ser.isOpen():
            NOEND = False
            self.thread.join()
            self.ser.close()
            self.comopenbtnstr.set("打开串口")
        else:
            # None表示等待时间为一直等待
            self.ser, ret = self.open_seri(self.cbcomportvar.get(),self.cbcombpsvar.get(), None)
            # 判断串口是否成功打开
            if ret==True:
                self.comopenbtnstr.set("关闭串口")
 
    def showinterface(self):
        self.root = Tk()
        self.root.title("串口调试助手")
        #self.root.geometry("560x500")
 
        # 打开串口按钮
        self.comopenflagstr = StringVar()
        self.comopenflagstr.set("串口状态")
        self.labelname = Label(self.root,textvariable = self.comopenflagstr)
        self.comopenbtnstr = StringVar()
        self.comopenbtnstr.set("打开串口")
        self.btnopencom = Button(self.root,textvariable = self.comopenbtnstr,command = self.btn_hit)
 

        # 获取存在的端口号
        self.comlist=[]
        port_list = list(serial.tools.list_ports.comports())
        if len(port_list) == 0:
            print('无可用串口')
            self.comlist.append("无串口")
            self.btnopencom['state'] = 'disabled'
        else:
            for i in range(0,len(port_list)):
                plist_com = port_list[i]
                plist_com = list(port_list[i])
                self.comlist.append(plist_com[0])
 
        self.labelport = Label(self.root,text="端口号")
        self.cbcomportvar = StringVar()
        self.cbport = Combobox(self.root,textvariable=self.cbcomportvar) 
        self.cbport["value"]=tuple(self.comlist)
        self.cbport.current(0)
 
        # 波特率
        self.labelbps = Label(self.root,text="波特率")
        self.cbcombpsvar = StringVar()
        self.cbbps = Combobox(self.root,textvariable=self.cbcombpsvar) 
        self.cbbps["value"]=("115200")
        self.cbbps.current(0)
 
        # 发送数据    
        self.btncomsend = Button(self.root,text = "发送",command = self.btn_sendcmd)
        self.sendx=StringVar()
        self.sendcmd=Entry(self.root,textvariable=self.sendx)
 
        # 接收数据    
        self.labelrecv = Label(self.root,text="接收的数据")
        self.recv = Text(self.root, width=80, height= 24)
        self.recv_clean = Button(self.root,text = "清空",command = self.btn_clean_recv)
        
        # grid布局
        self.labelname.grid(row=0,column=0, pady=2, padx=3,sticky=W)
        self.btnopencom.grid(row=0,column=1, pady=2, padx=3,sticky=E+W)
 
        self.labelport.grid(row=1,column=0, pady=2, padx=3,sticky=W)
        self.cbport.grid(row=1,column=1, pady=2, padx=3,sticky=E+W)
 
        self.labelbps.grid(row=2,column=0, pady=2, padx=3,sticky=W)
        self.cbbps.grid(row=2,column=1, pady=2, padx=3,sticky=E+W)
        self.btncomsend.grid(row=3,column=0,pady=2, padx=3,sticky=W)
        self.sendcmd.grid(row=3,column=1,pady=2, padx=3,sticky=W+E)
 
        self.labelrecv.grid(row=4,column=0,columnspan=2,padx=3,pady=3,sticky=W)
        self.recv_clean.grid(row=4, column=1,pady=2, padx=3,sticky=W)
        self.recv.grid(row=7,column=0,columnspan=2,padx=3,pady=3,sticky=W+E)
        
        # 阻止Python GUI的大小调整
        self.root.resizable(0,0) 
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.root.mainloop()
 
    def btn_clean_recv(self):
         self.recv.delete(1.0, END)
 
    def btn_sendcmd(self):
        if self.ser.isOpen():
            #text = b'c'
            text = self.sendx.get()
            self.ser.write(str.encode(text))
 
 
if __name__ == "__main__":     
   myserial = cbh_Serial()

 

 

原创文章,作者:Carrie001128,如若转载,请注明出处:https://blog.ytso.com/278460.html

(0)
上一篇 2022年8月2日
下一篇 2022年8月2日

相关推荐

发表回复

登录后才能评论