标签: 漂流小江 2020年2月6日
一、串口调试助手
1.QT界面实现
(1)界面面图片展示
(图示1处函数为自定义函数)
)
(2)界面代码展示
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'chuankou.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(775, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.sendbutton = QtWidgets.QPushButton(self.centralwidget)
self.sendbutton.setGeometry(QtCore.QRect(115, 266, 91, 31))
font = QtGui.QFont()
font.setPointSize(15)
self.sendbutton.setFont(font)
self.sendbutton.setObjectName("sendbutton")
self.sendcom = QtWidgets.QComboBox(self.centralwidget)
self.sendcom.setGeometry(QtCore.QRect(100, 60, 131, 51))
font = QtGui.QFont()
font.setPointSize(15)
self.sendcom.setFont(font)
self.sendcom.setLayoutDirection(QtCore.Qt.LeftToRight)
self.sendcom.setObjectName("sendcom")
self.sendcom.addItem("")
self.sendcom.setItemText(0, "")
self.sendbot = QtWidgets.QComboBox(self.centralwidget)
self.sendbot.setGeometry(QtCore.QRect(100, 160, 131, 41))
font = QtGui.QFont()
font.setPointSize(15)
self.sendbot.setFont(font)
self.sendbot.setObjectName("sendbot")
self.sendbot.addItem("")
self.sendbot.addItem("")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(20, 60, 71, 41))
font = QtGui.QFont()
font.setPointSize(15)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(20, 150, 71, 41))
font = QtGui.QFont()
font.setPointSize(15)
self.label_2.setFont(font)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.recvddata = QtWidgets.QTextEdit(self.centralwidget)
self.recvddata.setGeometry(QtCore.QRect(240, 20, 371, 281))
font = QtGui.QFont()
font.setPointSize(13)
self.recvddata.setFont(font)
self.recvddata.setObjectName("recvddata")
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setGeometry(QtCore.QRect(350, 310, 131, 41))
font = QtGui.QFont()
font.setPointSize(15)
self.label_3.setFont(font)
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName("label_3")
self.inputdata = QtWidgets.QTextEdit(self.centralwidget)
self.inputdata.setGeometry(QtCore.QRect(260, 360, 321, 81))
font = QtGui.QFont()
font.setPointSize(15)
self.inputdata.setFont(font)
self.inputdata.setObjectName("inputdata")
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setGeometry(QtCore.QRect(500, 470, 151, 41))
font = QtGui.QFont()
font.setPointSize(15)
self.label_4.setFont(font)
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
self.label_4.setObjectName("label_4")
self.senddata = QtWidgets.QPushButton(self.centralwidget)
self.senddata.setGeometry(QtCore.QRect(120, 380, 91, 31))
font = QtGui.QFont()
font.setPointSize(15)
self.senddata.setFont(font)
self.senddata.setObjectName("senddata")
self.checknline = QtWidgets.QCheckBox(self.centralwidget)
self.checknline.setGeometry(QtCore.QRect(210, 460, 211, 51))
font = QtGui.QFont()
font.setPointSize(15)
self.checknline.setFont(font)
self.checknline.setLayoutDirection(QtCore.Qt.LeftToRight)
self.checknline.setObjectName("checknline")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 775, 18))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.sendbutton.clicked.connect(MainWindow.open_com)
self.sendcom.activated['QString'].connect(MainWindow.port_changed)
self.sendbot.activated['QString'].connect(MainWindow.baud_changed)
self.senddata.clicked.connect(MainWindow.senddatatocom)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.sendbutton.setStatusTip(_translate("MainWindow", "点击连接"))
self.sendbutton.setText(_translate("MainWindow", "连接"))
self.sendbot.setItemText(0, _translate("MainWindow", "9600"))
self.sendbot.setItemText(1, _translate("MainWindow", "115200"))
self.label.setText(_translate("MainWindow", "串口"))
self.label_2.setText(_translate("MainWindow", "波特率"))
self.label_3.setText(_translate("MainWindow", "接收显示"))
self.label_4.setText(_translate("MainWindow", "发送数据"))
self.senddata.setText(_translate("MainWindow", "发送"))
self.checknline.setText(_translate("MainWindow", "发送新行"))
1.界面逻辑实现代码
(1)逻辑代码展示
import serial
import sys
import struct
import serial.tools.list_ports
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import *
from chuankou import *
########################
#函数区
####################################################
# 串口函数区
def get_com_list():
Com_List = []
plist = list(serial.tools.list_ports.comports())
if len(plist) > 0:
for i in range(len(plist)):
Com_List.append(list(plist[i])[0])
return Com_List
#####################################################
#创建主界面
class MyWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.setupUi(self)
self.setWindowIcon(QIcon('serialscope.ico'))#程序的图标
#创建一个定时器
self.sendbutton.setToolTip('点击打开串口')
# 初始化一个定时器,防止while循环读串口时陷入死循环
self.timer = QTimer(self) # 初始化一个定时器
self.timer.timeout.connect(self.time_out) # 计时结束调用time_out()
def show_dialog(self, str=''):
# 创建QDialog对象
dialog = QDialog()
# 创建按钮到新创建的dialog对象中
lb = QLabel(str, dialog)
lb.move(50, 50)
# btn = QPushButton('ok', dialog)
# 移动按钮,设置dialog的标题
# btn.move(50, 50)
dialog.setWindowTitle("Dialog")
# 设置窗口的属性为Qt.ApplicationModal模态,用户只有关闭d窗后,才能关闭主界面
dialog.setWindowModality(Qt.NonModal)
dialog.exec_()
#定时100ms读一次数据,未用while,防止程序陷入死循环
def time_out(self): # 按时接收数据
global ser, timer_value
# data = ser.readline()
data = ser.read_all() # 读取串口中的数据
if data != b'':
data = data.decode('utf-8')
self.recvddata.append(data)
self.timer.start(timer_value) # 原本不需要重启,是考虑到变时定时
#######################
def open_com(self):
global ser, serialPort, baudRate, com_list
com_list = get_com_list() # 得到可用串口
if com_list != []: # 如果一切正常,串口正常打开
if serialPort != None: # 如果也没出过什么叉子
ser.port = serialPort
ser.baudrate = baudRate
if self.sendbutton.text() == '连接':
ser.open() # 上述 *** 作已经打开串口,不能再次打开端口
self.timer.start(timer_value) # 定时处理一次接收的数据
self.sendbutton.setText("关闭")
self.sendbutton.setToolTip('点击关闭串口')
print('串口已连接')
# while True:
# data = ser.read_all() # 读取串口中的数据
# if data != b'':
# data = data.decode('utf-8')
# print(data)
else:
self.timer.stop()
ser.close() # 关闭端口
self.sendbutton.setText("连接")
self.sendbutton.setToolTip('点击打开串口')
print('串口已断开')
else: # 如果中途出过叉子,先修复
myWin.port_combo.clear()
for i in range(len(com_list)): # 将可用串口填充到下拉框
myWin.sendcom.addItem(com_list[i])
serialPort = com_list[0] # 串口号
else: # 已经坏透了,显示提示框
serialPort = None
myWin.sendcom.clear()
myWin.show_dialog(str='请先打开串口')
#向串口发送数据
def senddatatocom(self):
global serialPort, ser
if self.sendbutton.text() == '关闭'and serialPort != None:
send_str=self.inputdata.toPlainText()
state_checknline=self.checknline.isChecked()
if state_checknline == True:#选择是否换行
print('发送新行')
send_str += '\r\n'
ser.write(send_str.encode('utf-8'))#将要发送的数据写入串口
print('发送数据为:'+send_str)
else:
self.show_dialog(str='请先打开串口')
#改变串口
def port_changed(self, text):
global serialPort
serialPort = text
print('串口:' + serialPort)
ser.port = serialPort
#改变波特率
def baud_changed(self, text):
global baudRate
baudRate = int(text)
print(baudRate)
ser.baudrate=baudRate
####################################################
#全局变量及先行代码
app = QApplication(sys.argv)
myWin = MyWindow()
myWin.show()
# myWin.Port_send() #开机有可用串口则自动打开串口
baudRate = 115200 # 波特率
timer_value=100
#################################################
ser=serial.Serial(timeout=0.5)
com_list=get_com_list() #得到可用串口
if com_list!=[]:
for i in range(len(com_list)): # 将可用串口填充到下拉框
myWin.sendcom.addItem(com_list[i])
serialPort = com_list[0] # 串口号
else:
serialPort = None
myWin.show_dialog(str='请先打开串口')
sys.exit(app.exec_())
(2)逻辑效果展示二、PyQt5使用技巧总结
1.多线程的三种使用
*背景:
*在PyQt中所有的窗口都在UI主线程中(就是执行了QApplication.exec()的线程,在这个线程中执行耗时的 *** 作阻塞UI线程,从而导致窗口停止响应,加入多线程机制会很好的解决这个问题。
(1)计时器模块QTimer
实现:
#首先引入QTimer模块
from PyQt5.QtCore import Qt, QTimer
#****************************************************
# 初始化一个定时器,防止while循环读串口时陷入死循环
self.timer = QTimer(self) # 初始化一个定时器
self.timer.timeout.connect(self.time_out) # 计时结束调用time_out()
#****************************************************
#定时100ms读一次数据,未用while,防止程序陷入死循环
def time_out(self): # 按时接收数据
pass
self.timer.start(timer_value) # 原本不需要重启,是考虑到变时定时
#****************************************************
self.timer.start(timer_value) # 定时处理一次接收的数据,timer_value为设置的时间,单位ms
#****************************************************
self.timer.stop()#停止计时
(2)线程模块QThread
实现:
#首先引入QTimer模块
from PyQt5.QtCore import Qt, QTimer
#****************************************************
#要使用QThread开始一个线程,需创建其子类,覆盖其QThread.run()函数,
#如:
class Thread(QThread):
def__init__(self):
super(Thread,self).__init__()
def run(self):
#相关代码
pass
#****************************************************
#接下来创建一个新的线程
thread=Thread()
thread.start()
#****************************************************
此笔记写的有些粗糙,更详细笔记我已在本人公众号更新,或者想要了解更多或者想要获取该工程代码请关注微信公众号“漂流小江”,还可以在b站观看小江的视频课程。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)