这篇文章主要介绍了python之pyqt多线程串口代码分析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
这篇博客主要记录一下pyqt多线程串口的主要代码分析,文末会有工程的源代码文件
首先,从pycharm启动qtdesigner
之前给客户做的上位机,保密起见,删减了大部分的框图构件,但不影响本篇串口教程
qtdesigner界面如下:
忽略 添加数据以及表格数据显示,这里用不到
着重讲一下类的构成
新建一个串口类serialthread,继承自qtcore.qthread,实现全部的串口收发功能
class serialthread(qtcore.qthread):
datareadoutsignal = pyqtsignal(str) def __init__(self, parent = none, portname = 'com3', baudrate = 9600, parity = 'n', bytesize = 8, stopbits = 1, timeout = none):
super(serialthread, self).__init__(parent)
self.m_serialport = serial.serial()
self.m_serialport.port = portname
self.m_serialport.baudrate = baudrate
self.m_serialport.parity = parity
self.m_serialport.bytesize = bytesize
self.m_serialport.stopbits = stopbits
self.m_serialport.timeout = timeout
self.openscom() def openscom(self):
try:
self.m_serialport.open()
self.m_serialport.setrts(true)
self.m_serialport.setdtr(true) except exception as ex:
print(ex) return ex def scomsendonedata(self,datain):
if isinstance(datain,int):
listtemp = []
listtemp.append(datain)
d = bytes(listtemp)
self.m_serialport.write(d) else: if isinstance(datain,str):
d = datain.encode('utf-8')
self.m_serialport.write(d) def scomgetintdata(self):
n = self.m_serialport.inwaiting() if n:
data = self.m_serialport.read(n).hex() #writefile
print(data) def scomgetstrdata(self):
if self.m_serialport.is_open:
n = self.m_serialport.inwaiting() if n > 0:
data = self.m_serialport.read(n).decode('gb2312',errors='ignore') return data def run(self):
cnt = 50
while cnt <= 3000:
sendstr = str(cnt) if len(sendstr) == 2:
sendstr = '00' + sendstr else: if len(sendstr) == 3:
sendstr = '0' + sendstr
self.scomsendonedata('set' + sendstr + 'v')
cnt = cnt + 5
print('此时设置电压为:' + sendstr + 'v')
time.sleep(2)
函数功能见名知意,此处不表。这里主要讲一下run函数,run函数实现了一次循环,50到3000步进取5,发送内容是set0050v到set3000v,当然,我这样做是业务需求,如果并不需要这个功能,run函数可以写成
def run(self):
while true:
time.sleep(2)
界面我们用qtdesigner制作的ui文件通过pyuic生成py文件
生成的代码如下(太长,只留前几行)
# -*- coding: utf-8 -*-# form implementation generated from reading ui file 'cashupdateui11v.ui'## created by: pyqt5 ui code generator 5.6## warning! all changes made in this file will be lost!from pyqt5 import qtcore, qtgui, qtwidgetsclass ui_cash(object):
def setupui(self, cash):
**
**
**
此时,新建一个类mywindow,继承qmainwindow和ui_cash,并在类内部,创建serialthread成员
总体代码如下:
class mywindow(qmainwindow,ui_cash):
def __init__(self):
super(mywindow,self).__init__()
self.scomlist = []
self.threadlist = []
self.setupui(self)
self.actionopen.triggered.connect(self.openmsg)
self.actionsave.triggered.connect(self.savemsg)
self.pushbutton.clicked.connect(self.scomautofind)
self.adddatabutton.clicked.connect(self.getrhandt)
self.tablewidget.setcolumncount(5)
self.tablewidget.setrowcount(1)
self.tablewidget.sethorizontalheaderlabels(['11', '22', '33', '44', '55'])
self.tablerowcnt = 0
self.tablecolumncnt = 0
self.threadcomid = 0
self.adddatasignal = pyqtsignal(str)
self.datadict = {'rhldy':0,'tldy':0,'meart':0,'voltport':0} def getmcudata(self):
if self.threadcomid == 0:
self.showmsgbox('请先连接串口') else:
self.threadcomid.scomsendonedata(' 5501aa')
time.sleep(0.1)
strt = self.threadcomid.scomgetstrdata() if strt is none:
self.showmsgbox('请将串口线连接到电路板') return none
print(strt)
self.datadict['voltport'] = strt[4:-3] + '.' + strt[-3:-2]
self.threadcomid.scomsendonedata(' 5502aa')
time.sleep(0.1)
strt = self.threadcomid.scomgetstrdata() if strt is none:
self.showmsgbox('请将串口线连接到电路板') return none
print(strt)
self.datadict['meart'] = strt[4:-4] + '.' + strt[-4:-2] return 1
def inserttablenewline(self):
self.tablewidget.setitem(self.tablerowcnt, 0, qtablewidgetitem(self.datadict['rhldy']))
self.tablewidget.setitem(self.tablerowcnt, 1, qtablewidgetitem(self.datadict['tldy']))
self.tablewidget.setitem(self.tablerowcnt, 2, qtablewidgetitem(self.datadict['meart']))
self.tablewidget.setitem(self.tablerowcnt, 3, qtablewidgetitem(self.datadict['voltport']))
self.tablewidget.setitem(self.tablerowcnt, 4, qtablewidgetitem(str(datetime.date.today())+' '+str(datetime.datetime.today().hour)+':'+str(datetime.datetime.today().minute)))
self.tablerowcnt += 1
self.tablewidget.insertrow(self.tablerowcnt) def openmsg(self):
file,ok = qfiledialog.getopenfilename(self,"打开记录表","c:/",".txt") def getrhandt(self):
if self.threadcomid == 0:
self.showmsgbox('请先连接串口') else:
data,ok = qinputdialog.gettext(self, "露点仪数据", "按如下格式记录:\n rh空格t\n示例:\n rh(0~100):66.6\n t(0~200):9.8\n 输入:66.6 9.8", qlineedit.normal, "66.6 9.8" ) if ok == true:
data = re.findall('^[0-9]+\.[0-9]+\s+[0-9]+\.[0-9]+$', data.rstrip()) if len(data) == 0:
self.showmsgbox('数据格式有误,重新录入') else:
data = data[0].split()
print(data)
self.datadict['rhldy'] = data[0]
self.datadict['tldy'] = data[1] if self.getmcudata() is none: return none
print(self.datadict)
self.inserttablenewline() else:
self.showmsgbox('请重新录入数据') def showmsgbox(self,strtoshow):
qmessagebox.warning(self,'提示',strtoshow,qmessagebox.ok) def savemsg(self):
file,ok = qfiledialog.getsavefilename(self,"保存记录表","c:/",".txt") def scomautofind(self):
self.pushbutton.setdisabled(true)
self.scomlist = list(serial.tools.list_ports.comports()) if len(self.scomlist) <= 0:
self.showmsgbox('未发现串口,请检查线缆连接')
self.pushbutton.setdisabled(false) else:
comnum = len(self.scomlist)
print(str(comnum) + 'scom is found') while comnum:
comnum = comnum - 1
if "usb" in str(self.scomlist[comnum]):
self.threadcomid = serialthread(portname=self.scomlist[comnum][0])
self.threadcomid.start()
self.graphicsview.setstylesheet("background-color: rgb(0, 255, 0);")
print(str(self.scomlist[comnum]) + ' is added')
由于我用的是rs232转usb接入电脑,设备名称是usb-serial ch340,当然还有其他rs232转usb芯片,如pl2303等。我这里就单独检查usb是否在设备名称中,没有检查全名,这里要根据实际需求变动
最后就是main了,没什么特别
if __name__ == "__main__":
app = qapplication(sys.argv)
myshow = mywindow()
myshow.show() print('程序终止')
sys.exit(app.exec_())
看一下实际运行效果:
实际运行,(忽略 添加数据 与 数据记录表….)
点击connect后,
当然点击添加数据也是没问题的哈
奉上全部工程文件,链接如下:
https://download.csdn.net/download/ysgjiangsu/10324162
以上就是python之pyqt多线程串口代码分析的详细内容。