欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用Python3+PyQT5+Pyserial 实现简单的串口工具方法

程序员文章站 2023-11-30 10:49:04
练手项目,先上图 先实现一个简单的串口工具,为之后的上位机做准备 代码如下: github 下载地址 pyserial_demo.py import...

练手项目,先上图

使用Python3+PyQT5+Pyserial 实现简单的串口工具方法

先实现一个简单的串口工具,为之后的上位机做准备

代码如下:

github 下载地址

pyserial_demo.py

import sys
import serial
import serial.tools.list_ports
from pyqt5 import qtwidgets
from pyqt5.qtwidgets import qmessagebox
from pyqt5.qtcore import qtimer
from ui_demo_1 import ui_form


class pyqt5_serial(qtwidgets.qwidget, ui_form):
  def __init__(self):
    super(pyqt5_serial, self).__init__()
    self.setupui(self)
    self.init()
    self.setwindowtitle("串口小助手")
    self.ser = serial.serial()
    self.port_check()

    # 接收数据和发送数据数目置零
    self.data_num_received = 0
    self.lineedit.settext(str(self.data_num_received))
    self.data_num_sended = 0
    self.lineedit_2.settext(str(self.data_num_sended))

  def init(self):
    # 串口检测按钮
    self.s1__box_1.clicked.connect(self.port_check)

    # 串口信息显示
    self.s1__box_2.currenttextchanged.connect(self.port_imf)

    # 打开串口按钮
    self.open_button.clicked.connect(self.port_open)

    # 关闭串口按钮
    self.close_button.clicked.connect(self.port_close)

    # 发送数据按钮
    self.s3__send_button.clicked.connect(self.data_send)

    # 定时发送数据
    self.timer_send = qtimer()
    self.timer_send.timeout.connect(self.data_send)
    self.timer_send_cb.statechanged.connect(self.data_send_timer)

    # 定时器接收数据
    self.timer = qtimer(self)
    self.timer.timeout.connect(self.data_receive)

    # 清除发送窗口
    self.s3__clear_button.clicked.connect(self.send_data_clear)

    # 清除接收窗口
    self.s2__clear_button.clicked.connect(self.receive_data_clear)

  # 串口检测
  def port_check(self):
    # 检测所有存在的串口,将信息存储在字典中
    self.com_dict = {}
    port_list = list(serial.tools.list_ports.comports())
    self.s1__box_2.clear()
    for port in port_list:
      self.com_dict["%s" % port[0]] = "%s" % port[1]
      self.s1__box_2.additem(port[0])
    if len(self.com_dict) == 0:
      self.state_label.settext(" 无串口")

  # 串口信息
  def port_imf(self):
    # 显示选定的串口的详细信息
    imf_s = self.s1__box_2.currenttext()
    if imf_s != "":
      self.state_label.settext(self.com_dict[self.s1__box_2.currenttext()])

  # 打开串口
  def port_open(self):
    self.ser.port = self.s1__box_2.currenttext()
    self.ser.baudrate = int(self.s1__box_3.currenttext())
    self.ser.bytesize = int(self.s1__box_4.currenttext())
    self.ser.stopbits = int(self.s1__box_6.currenttext())
    self.ser.parity = self.s1__box_5.currenttext()

    try:
      self.ser.open()
    except:
      qmessagebox.critical(self, "port error", "此串口不能被打开!")
      return none

    # 打开串口接收定时器,周期为2ms
    self.timer.start(2)

    if self.ser.isopen():
      self.open_button.setenabled(false)
      self.close_button.setenabled(true)
      self.formgroupbox1.settitle("串口状态(已开启)")

  # 关闭串口
  def port_close(self):
    self.timer.stop()
    self.timer_send.stop()
    try:
      self.ser.close()
    except:
      pass
    self.open_button.setenabled(true)
    self.close_button.setenabled(false)
    self.lineedit_3.setenabled(true)
    # 接收数据和发送数据数目置零
    self.data_num_received = 0
    self.lineedit.settext(str(self.data_num_received))
    self.data_num_sended = 0
    self.lineedit_2.settext(str(self.data_num_sended))
    self.formgroupbox1.settitle("串口状态(已关闭)")

  # 发送数据
  def data_send(self):
    if self.ser.isopen():
      input_s = self.s3__send_text.toplaintext()
      if input_s != "":
        # 非空字符串
        if self.hex_send.ischecked():
          # hex发送
          input_s = input_s.strip()
          send_list = []
          while input_s != '':
            try:
              num = int(input_s[0:2], 16)
            except valueerror:
              qmessagebox.critical(self, 'wrong data', '请输入十六进制数据,以空格分开!')
              return none
            input_s = input_s[2:].strip()
            send_list.append(num)
          input_s = bytes(send_list)
        else:
          # ascii发送
          input_s = (input_s + '\r\n').encode('utf-8')

        num = self.ser.write(input_s)
        self.data_num_sended += num
        self.lineedit_2.settext(str(self.data_num_sended))
    else:
      pass

  # 接收数据
  def data_receive(self):
    try:
      num = self.ser.inwaiting()
    except:
      self.port_close()
      return none
    if num > 0:
      data = self.ser.read(num)
      num = len(data)
      # hex显示
      if self.hex_receive.checkstate():
        out_s = ''
        for i in range(0, len(data)):
          out_s = out_s + '{:02x}'.format(data[i]) + ' '
        self.s2__receive_text.insertplaintext(out_s)
      else:
        # 串口接收到的字符串为b'123',要转化成unicode字符串才能输出到窗口中去
        self.s2__receive_text.insertplaintext(data.decode('iso-8859-1'))

      # 统计接收字符的数量
      self.data_num_received += num
      self.lineedit.settext(str(self.data_num_received))

      # 获取到text光标
      textcursor = self.s2__receive_text.textcursor()
      # 滚动到底部
      textcursor.moveposition(textcursor.end)
      # 设置光标到text中去
      self.s2__receive_text.settextcursor(textcursor)
    else:
      pass

  # 定时发送数据
  def data_send_timer(self):
    if self.timer_send_cb.ischecked():
      self.timer_send.start(int(self.lineedit_3.text()))
      self.lineedit_3.setenabled(false)
    else:
      self.timer_send.stop()
      self.lineedit_3.setenabled(true)

  # 清除显示
  def send_data_clear(self):
    self.s3__send_text.settext("")

  def receive_data_clear(self):
    self.s2__receive_text.settext("")


if __name__ == '__main__':
  app = qtwidgets.qapplication(sys.argv)
  myshow = pyqt5_serial()
  myshow.show()
  sys.exit(app.exec_())

ui_demo_1.py

# -*- coding: utf-8 -*-

# form implementation generated from reading ui file 'demo_1.ui'
#
# created by: pyqt5 ui code generator 5.6
#
# warning! all changes made in this file will be lost!

from pyqt5 import qtcore, qtgui, qtwidgets

class ui_form(object):
  def setupui(self, form):
    form.setobjectname("form")
    form.resize(707, 458)
    self.formgroupbox = qtwidgets.qgroupbox(form)
    self.formgroupbox.setgeometry(qtcore.qrect(20, 20, 167, 301))
    self.formgroupbox.setobjectname("formgroupbox")
    self.formlayout = qtwidgets.qformlayout(self.formgroupbox)
    self.formlayout.setcontentsmargins(10, 10, 10, 10)
    self.formlayout.setspacing(10)
    self.formlayout.setobjectname("formlayout")
    self.s1__lb_1 = qtwidgets.qlabel(self.formgroupbox)
    self.s1__lb_1.setobjectname("s1__lb_1")
    self.formlayout.setwidget(0, qtwidgets.qformlayout.labelrole, self.s1__lb_1)
    self.s1__box_1 = qtwidgets.qpushbutton(self.formgroupbox)
    self.s1__box_1.setautorepeatinterval(100)
    self.s1__box_1.setdefault(true)
    self.s1__box_1.setobjectname("s1__box_1")
    self.formlayout.setwidget(0, qtwidgets.qformlayout.fieldrole, self.s1__box_1)
    self.s1__lb_2 = qtwidgets.qlabel(self.formgroupbox)
    self.s1__lb_2.setobjectname("s1__lb_2")
    self.formlayout.setwidget(1, qtwidgets.qformlayout.labelrole, self.s1__lb_2)
    self.s1__box_2 = qtwidgets.qcombobox(self.formgroupbox)
    self.s1__box_2.setobjectname("s1__box_2")
    self.formlayout.setwidget(1, qtwidgets.qformlayout.fieldrole, self.s1__box_2)
    self.s1__lb_3 = qtwidgets.qlabel(self.formgroupbox)
    self.s1__lb_3.setobjectname("s1__lb_3")
    self.formlayout.setwidget(3, qtwidgets.qformlayout.labelrole, self.s1__lb_3)
    self.s1__box_3 = qtwidgets.qcombobox(self.formgroupbox)
    self.s1__box_3.setobjectname("s1__box_3")
    self.s1__box_3.additem("")
    self.s1__box_3.additem("")
    self.s1__box_3.additem("")
    self.s1__box_3.additem("")
    self.s1__box_3.additem("")
    self.s1__box_3.additem("")
    self.s1__box_3.additem("")
    self.s1__box_3.additem("")
    self.s1__box_3.additem("")
    self.s1__box_3.additem("")
    self.s1__box_3.additem("")
    self.s1__box_3.additem("")
    self.formlayout.setwidget(3, qtwidgets.qformlayout.fieldrole, self.s1__box_3)
    self.s1__lb_4 = qtwidgets.qlabel(self.formgroupbox)
    self.s1__lb_4.setobjectname("s1__lb_4")
    self.formlayout.setwidget(4, qtwidgets.qformlayout.labelrole, self.s1__lb_4)
    self.s1__box_4 = qtwidgets.qcombobox(self.formgroupbox)
    self.s1__box_4.setobjectname("s1__box_4")
    self.s1__box_4.additem("")
    self.s1__box_4.additem("")
    self.s1__box_4.additem("")
    self.s1__box_4.additem("")
    self.formlayout.setwidget(4, qtwidgets.qformlayout.fieldrole, self.s1__box_4)
    self.s1__lb_5 = qtwidgets.qlabel(self.formgroupbox)
    self.s1__lb_5.setobjectname("s1__lb_5")
    self.formlayout.setwidget(5, qtwidgets.qformlayout.labelrole, self.s1__lb_5)
    self.s1__box_5 = qtwidgets.qcombobox(self.formgroupbox)
    self.s1__box_5.setobjectname("s1__box_5")
    self.s1__box_5.additem("")
    self.formlayout.setwidget(5, qtwidgets.qformlayout.fieldrole, self.s1__box_5)
    self.open_button = qtwidgets.qpushbutton(self.formgroupbox)
    self.open_button.setobjectname("open_button")
    self.formlayout.setwidget(7, qtwidgets.qformlayout.spanningrole, self.open_button)
    self.close_button = qtwidgets.qpushbutton(self.formgroupbox)
    self.close_button.setobjectname("close_button")
    self.formlayout.setwidget(8, qtwidgets.qformlayout.spanningrole, self.close_button)
    self.s1__lb_6 = qtwidgets.qlabel(self.formgroupbox)
    self.s1__lb_6.setobjectname("s1__lb_6")
    self.formlayout.setwidget(6, qtwidgets.qformlayout.labelrole, self.s1__lb_6)
    self.s1__box_6 = qtwidgets.qcombobox(self.formgroupbox)
    self.s1__box_6.setobjectname("s1__box_6")
    self.s1__box_6.additem("")
    self.formlayout.setwidget(6, qtwidgets.qformlayout.fieldrole, self.s1__box_6)
    self.state_label = qtwidgets.qlabel(self.formgroupbox)
    self.state_label.settext("")
    self.state_label.settextformat(qtcore.qt.autotext)
    self.state_label.setscaledcontents(true)
    self.state_label.setalignment(qtcore.qt.alignright|qtcore.qt.aligntrailing|qtcore.qt.alignvcenter)
    self.state_label.setobjectname("state_label")
    self.formlayout.setwidget(2, qtwidgets.qformlayout.spanningrole, self.state_label)
    self.verticalgroupbox = qtwidgets.qgroupbox(form)
    self.verticalgroupbox.setgeometry(qtcore.qrect(210, 20, 401, 241))
    self.verticalgroupbox.setobjectname("verticalgroupbox")
    self.verticallayout = qtwidgets.qvboxlayout(self.verticalgroupbox)
    self.verticallayout.setcontentsmargins(10, 10, 10, 10)
    self.verticallayout.setobjectname("verticallayout")
    self.s2__receive_text = qtwidgets.qtextbrowser(self.verticalgroupbox)
    self.s2__receive_text.setobjectname("s2__receive_text")
    self.verticallayout.addwidget(self.s2__receive_text)
    self.verticalgroupbox_2 = qtwidgets.qgroupbox(form)
    self.verticalgroupbox_2.setgeometry(qtcore.qrect(210, 280, 401, 101))
    self.verticalgroupbox_2.setobjectname("verticalgroupbox_2")
    self.verticallayout_2 = qtwidgets.qvboxlayout(self.verticalgroupbox_2)
    self.verticallayout_2.setcontentsmargins(10, 10, 10, 10)
    self.verticallayout_2.setobjectname("verticallayout_2")
    self.s3__send_text = qtwidgets.qtextedit(self.verticalgroupbox_2)
    self.s3__send_text.setobjectname("s3__send_text")
    self.verticallayout_2.addwidget(self.s3__send_text)
    self.s3__send_button = qtwidgets.qpushbutton(form)
    self.s3__send_button.setgeometry(qtcore.qrect(620, 310, 61, 31))
    self.s3__send_button.setobjectname("s3__send_button")
    self.s3__clear_button = qtwidgets.qpushbutton(form)
    self.s3__clear_button.setgeometry(qtcore.qrect(620, 350, 61, 31))
    self.s3__clear_button.setobjectname("s3__clear_button")
    self.formgroupbox1 = qtwidgets.qgroupbox(form)
    self.formgroupbox1.setgeometry(qtcore.qrect(20, 340, 171, 101))
    self.formgroupbox1.setobjectname("formgroupbox1")
    self.formlayout_2 = qtwidgets.qformlayout(self.formgroupbox1)
    self.formlayout_2.setcontentsmargins(10, 10, 10, 10)
    self.formlayout_2.setspacing(10)
    self.formlayout_2.setobjectname("formlayout_2")
    self.label = qtwidgets.qlabel(self.formgroupbox1)
    self.label.setobjectname("label")
    self.formlayout_2.setwidget(0, qtwidgets.qformlayout.labelrole, self.label)
    self.label_2 = qtwidgets.qlabel(self.formgroupbox1)
    self.label_2.setobjectname("label_2")
    self.formlayout_2.setwidget(1, qtwidgets.qformlayout.labelrole, self.label_2)
    self.lineedit = qtwidgets.qlineedit(self.formgroupbox1)
    self.lineedit.setobjectname("lineedit")
    self.formlayout_2.setwidget(0, qtwidgets.qformlayout.fieldrole, self.lineedit)
    self.lineedit_2 = qtwidgets.qlineedit(self.formgroupbox1)
    self.lineedit_2.setobjectname("lineedit_2")
    self.formlayout_2.setwidget(1, qtwidgets.qformlayout.fieldrole, self.lineedit_2)
    self.hex_send = qtwidgets.qcheckbox(form)
    self.hex_send.setgeometry(qtcore.qrect(620, 280, 71, 16))
    self.hex_send.setobjectname("hex_send")
    self.hex_receive = qtwidgets.qcheckbox(form)
    self.hex_receive.setgeometry(qtcore.qrect(620, 40, 71, 16))
    self.hex_receive.setobjectname("hex_receive")
    self.s2__clear_button = qtwidgets.qpushbutton(form)
    self.s2__clear_button.setgeometry(qtcore.qrect(620, 80, 61, 31))
    self.s2__clear_button.setobjectname("s2__clear_button")
    self.timer_send_cb = qtwidgets.qcheckbox(form)
    self.timer_send_cb.setgeometry(qtcore.qrect(260, 390, 71, 16))
    self.timer_send_cb.setobjectname("timer_send_cb")
    self.lineedit_3 = qtwidgets.qlineedit(form)
    self.lineedit_3.setgeometry(qtcore.qrect(350, 390, 61, 20))
    self.lineedit_3.setalignment(qtcore.qt.alignright|qtcore.qt.aligntrailing|qtcore.qt.alignvcenter)
    self.lineedit_3.setobjectname("lineedit_3")
    self.dw = qtwidgets.qlabel(form)
    self.dw.setgeometry(qtcore.qrect(420, 390, 54, 20))
    self.dw.setobjectname("dw")
    self.verticalgroupbox.raise_()
    self.verticalgroupbox_2.raise_()
    self.formgroupbox.raise_()
    self.s3__send_button.raise_()
    self.s3__clear_button.raise_()
    self.formgroupbox.raise_()
    self.hex_send.raise_()
    self.hex_receive.raise_()
    self.s2__clear_button.raise_()
    self.timer_send_cb.raise_()
    self.lineedit_3.raise_()
    self.dw.raise_()

    self.retranslateui(form)
    qtcore.qmetaobject.connectslotsbyname(form)

  def retranslateui(self, form):
    _translate = qtcore.qcoreapplication.translate
    form.setwindowtitle(_translate("form", "form"))
    self.formgroupbox.settitle(_translate("form", "串口设置"))
    self.s1__lb_1.settext(_translate("form", "串口检测:"))
    self.s1__box_1.settext(_translate("form", "检测串口"))
    self.s1__lb_2.settext(_translate("form", "串口选择:"))
    self.s1__lb_3.settext(_translate("form", "波特率:"))
    self.s1__box_3.setitemtext(0, _translate("form", "115200"))
    self.s1__box_3.setitemtext(1, _translate("form", "2400"))
    self.s1__box_3.setitemtext(2, _translate("form", "4800"))
    self.s1__box_3.setitemtext(3, _translate("form", "9600"))
    self.s1__box_3.setitemtext(4, _translate("form", "14400"))
    self.s1__box_3.setitemtext(5, _translate("form", "19200"))
    self.s1__box_3.setitemtext(6, _translate("form", "38400"))
    self.s1__box_3.setitemtext(7, _translate("form", "57600"))
    self.s1__box_3.setitemtext(8, _translate("form", "76800"))
    self.s1__box_3.setitemtext(9, _translate("form", "12800"))
    self.s1__box_3.setitemtext(10, _translate("form", "230400"))
    self.s1__box_3.setitemtext(11, _translate("form", "460800"))
    self.s1__lb_4.settext(_translate("form", "数据位:"))
    self.s1__box_4.setitemtext(0, _translate("form", "8"))
    self.s1__box_4.setitemtext(1, _translate("form", "7"))
    self.s1__box_4.setitemtext(2, _translate("form", "6"))
    self.s1__box_4.setitemtext(3, _translate("form", "5"))
    self.s1__lb_5.settext(_translate("form", "校验位:"))
    self.s1__box_5.setitemtext(0, _translate("form", "n"))
    self.open_button.settext(_translate("form", "打开串口"))
    self.close_button.settext(_translate("form", "关闭串口"))
    self.s1__lb_6.settext(_translate("form", "停止位:"))
    self.s1__box_6.setitemtext(0, _translate("form", "1"))
    self.verticalgroupbox.settitle(_translate("form", "接受区"))
    self.verticalgroupbox_2.settitle(_translate("form", "发送区"))
    self.s3__send_text.sethtml(_translate("form", "<!doctype html public \"-//w3c//dtd html 4.0//en\" \"http://www.w3.org/tr/rec-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'simsun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">123456</p></body></html>"))
    self.s3__send_button.settext(_translate("form", "发送"))
    self.s3__clear_button.settext(_translate("form", "清除"))
    self.formgroupbox1.settitle(_translate("form", "串口状态"))
    self.label.settext(_translate("form", "已接收:"))
    self.label_2.settext(_translate("form", "已发送:"))
    self.hex_send.settext(_translate("form", "hex发送"))
    self.hex_receive.settext(_translate("form", "hex接收"))
    self.s2__clear_button.settext(_translate("form", "清除"))
    self.timer_send_cb.settext(_translate("form", "定时发送"))
    self.lineedit_3.settext(_translate("form", "1000"))
    self.dw.settext(_translate("form", "ms/次"))


以上这篇使用python3+pyqt5+pyserial 实现简单的串口工具方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。