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

时间:2022-02-20 20:05:50

练手项目,先上图

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

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

代码如下:

github 

pyserial_demo.py

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# -*- 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 实现简单的串口工具方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/windowsyun/article/details/80001488