一直以为pyQT是好的解决方案,后来发现tkinter也能简单的 应用。测试了下串口程序
import serial
import serial.tools.list_ports
import threading
from tkinter import *
from tkinter.ttk import *
"pip install pyserial"
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.ser.close()
print("退出串口前关闭串口")
self.root.destroy()
# 读数据的本体
def read_data(self,ser):
global DATA, NOEND
# 循环接收数据(线程实现)
while NOEND:
if self.ser.in_waiting:
#DATA = ser.read(ser.in_waiting).decode("gbk")
DATA = self.ser.read(self.ser.in_waiting)
#self.recvx.set(DATA.decode())
self.recvlistbox.insert(END,DATA.decode())
print(DATA)
if DATA == b'a':
print("cbh a")
def open_seri(self,portx, bps, timeout):
ret = False
try:
# 打开串口,并得到串口对象
self.ser = serial.Serial(portx, bps, timeout=timeout)
# 判断是否成功打开
if(self.ser.is_open):
ret = True
th = threading.Thread(target=self.read_data, args=(self.ser,)) # 创建一个子线程去等待读数据
th.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.ser.close()
print("已关闭,接下来打开串口")
self.comopenflagstr.set("串口已关闭")
self.comopenbtnstr.set("打开串口")
else:
print("等待打开")
#self.ser, ret = self.open_seri("COM12", 9600, None) # 串口com12、bps为9600,等待时间为永久
self.ser, ret = self.open_seri(self.cbcomportvar.get(),self.cbcombpsvar.get(), None) # 串口com3、bps为115200,等待时间为永久
if(ret==True):#判断串口是否成功打开
print("打开串口成功")
self.comopenflagstr.set("串口已打开")
self.comopenbtnstr.set("关闭串口")
def showinterface(self):
self.root = Tk()
self.root.title("Serail Testing By Dr Chen")
self.root.geometry("560x500")
#(1)打开串口按钮
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)
#(2)端口号
#获取存在的端口号
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 = list(port_list[i])
self.comlist.append(plist_com[i])
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)
#(3)波特率
self.labelbps = Label(self.root,text="波特率:")
self.cbcombpsvar = StringVar()
self.cbbps = Combobox(self.root,textvariable=self.cbcombpsvar)
self.cbbps["value"]=("9600","19200","38400","57600","115200")
self.cbbps.current(0)
#(4)发送数据
self.btncomsend = Button(self.root,text = "发送",command = self.btn_sendcmd)
self.sendx=StringVar()
self.sendcmd=Entry(self.root,textvariable=self.sendx)
#(5)接收数据
self.labelrecv = Label(self.root,text="接收的数据: ")
#self.recvx=StringVar()
#self.recvcmd=Entry(self.root,textvariable=self.recvx,width=40)
self.recvlistbox=Listbox(self.root,width=40)
#(4)grid布局
#labelname.grid(row=0,column=0,columnspan=2,sticky=E+W)
self.labelname.grid(row=0,column=0,padx=10,pady=10)
self.btnopencom.grid(row=0,column=1,padx=10,pady=10)
self.labelport.grid(row=1,column=0,padx=10,pady=10)
self.cbport.grid(row=1,column=1,padx=10,pady=10)
self.labelbps.grid(row=2,column=0,padx=10,pady=10)
self.cbbps.grid(row=2,column=1,padx=10,pady=10)
self.btncomsend.grid(row=3,column=0,padx=10,pady=10)
self.sendcmd.grid(row=3,column=1,padx=10,pady=10)
self.labelrecv.grid(row=4,column=0,columnspan=2,padx=10,pady=10,sticky=W)
self.recvlistbox.grid(row=5,column=0,columnspan=2,padx=10,pady=10,sticky=W)
self.root.resizable(0,0) #阻止Python GUI的大小调整
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
self.root.mainloop()
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()