最近开始学习python,还是去年暑假看过一些python语法,至今忘的差不多了,初中的时候学过E语言,当时初中制作些单机外挂之类(CF也做过,呃就是被封号了),最近玩的嵌入式有时候需要用到上位机,之前都是通过E语言做的,总觉得拿不出手,便想着换一个语言写一个上的了台面的
综合考虑,选择的PyQt5来编写上位机(因为python方便些嘛)
话不多说,正文开始:
(1)pycharm的安装
下载连接:http://www.jetbrains.com/pycharm/download/#section=windows
在这里我选择的是win10版本的pycharm,大家根据系统自行选择,安装过程就不在赘述了。
(2)PyQt5的安装
这个我搜索的时候大家都使用的是pip的方式安装,在这的话我推荐通过Pycharm来安装,比较方便些。
输入pyqt5后选择Install即可
(3)Designer.exe的使用(画界面)
打开designer开始绘制我们的界面:
绘制完成后由UI文件生成PY文件,此时就可以开始编写代码了
(4)编写程序
新建一个PY文件,我使用的名称为demo.py
先引入需要使用的库
import sys
import serial
import re
import binascii
import _thread
import time
import serial.tools.list_ports
from UI1 import Ui_MainWindow
from PyQt5 import QtWidgets
此时我们开始编写"MAIN"函数,将窗口显示出来,在这里我是选择了一个继承类,来继承通过PYQT5绘制的界面
class PC_software(QtWidgets.QMainWindow,Ui_MainWindow):
def __init__(self):
super(PC_software,self).__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
myshow = PC_software()
myshow.show()
sys.exit(app.exec_())
此时可以正常显示界面,但是没有功能,在PC_software下添加些其它函数
class PC_software(QtWidgets.QMainWindow,Ui_MainWindow):
def __init__(self):
super(PC_software,self).__init__()
self.setupUi(self)
self.ser = serial.Serial()
self.ser.baudrate = 9600
self.ser.bytesize = 8 # 设置数据位
self.ser.stopbits = 1 # 设置停止位
self.ser.parity = "N" # 设置校验位
self.pushButton_4.clicked.connect(self.Clear_text)
self.pushButton.clicked.connect(self.Screach_COM)
self.pushButton_2.clicked.connect(self.Clink_COM)
self.pushButton_3.clicked.connect(self.Data_Send)
self.Screach_COM()
def Clear_text(self):
self.textEdit.clear()
self.textBrowser.clear()
def Screach_COM(self):
self.comboBox.clear()
port_list = list(serial.tools.list_ports.comports())
com_numbers = len(port_list)
p1 = re.compile(r'[(](.*?)[)]', re.S)
for i in range(com_numbers):
com_list = str(port_list[i])
com_name = re.findall(p1, com_list)
com_name = str(com_name)
strlist = com_name.split("'")
self.comboBox.addItem(strlist[1])
def Clink_COM(self):
self.ser.port = self.comboBox.currentText()
if self.ser.is_open == True :
self.ser.close()
self.pushButton_2.setText('打开串口')
else:
self.ser.open()
self.pushButton_2.setText('关闭串口')
def Data_Send(self):
if self.ser.is_open == True:
self.ser.write((self.textEdit.toPlainText()+'\r\n').encode('gbk'))
#self.ser.write(str(binascii.b2a_hex(self.textEdit.toPlainText()))) #尝试编写HEX发送—失败
def Data_Recive(self):
while True:
if self.ser.is_open == True:
self.RC_data = self.ser.read_all()
if self.RC_data != b'':
#print('receive',self.RC_data.decode("gbk"))
self.textBrowser.insertPlainText(self.RC_data.decode("UTF-8"))
self.textBrowser.moveCursor(self.textBrowser.textCursor().End) # 文本框显示到底部
分别实现串口扫描、清空接收、打开/关闭串口、发送数据以及多线程的接收功能。
此时在主函数里面创建线程
_thread.start_new_thread(myshow.Data_Recive,())
此时运行一下程序并验证功能,发现OK
(5)遇到的问题
首先遇到的问题是无法再另一个文件里面使用其它的槽和对应函数,经过多个群里面的大佬检测后语句没有问题,最后发现是在主函数里面的映射有问题。(更深入了解了python语法的映射关系)
第二个问题是在使用serial库时的发送部分的转码,后来通过encode("GBK")来解决
第三个问题是接受部分,因为打开串口后要时刻准备接收,初始是使用了while True来实现试试监听,后来发现这样程序根本无法运行(无法进入界面),后来通过搜索,以线程的方式实现了互不干扰的实时监听。(python3里thread的库名称更改成了_thread)
谢谢大家观看!!