PyQt5+QtDesigner学习记录

标签: 漂流小江 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, QtWidgetsclass 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.translateMainWindow.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模态,用户只有关闭弹窗后,才能关闭主界面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_listcom_list = get_com_list()  # 得到可用串口if com_list != []:  # 如果一切正常,串口正常打开if serialPort != None:  # 如果也没出过什么叉子ser.port = serialPortser.baudrate = baudRateif 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 = NonemyWin.sendcom.clear()myWin.show_dialog(str='请先打开串口')#向串口发送数据def senddatatocom(self):global serialPort, serif 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 serialPortserialPort = textprint('串口:' + serialPort)ser.port = serialPort#改变波特率def baud_changed(self, text):global baudRatebaudRate = 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 = NonemyWin.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):  # 按时接收数据passself.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站观看小江的视频课程。

利用python快速开发一个上位机软件相关推荐

  1. 什么是核心竞争力——源自半导体行业,一个上位机软件开发工程师

    到底什么是核心竞争力 ----来自半导体行业,一个上位机软件开发工程师 我的工作侧重于软件二次开发,因行业问题,软件需要对电机,泵等硬件进行通信,按照一定的顺序对其进行控制,对Wafer进行加工,以达 ...

  2. windows和Linux利用Python快速搭建一个网站

    windows和Linux利用Python快速搭建一个网站 一.windows 步骤1:安装Python3(自行百度) 步骤2:在cmd窗口输入ipconfig查看本机ip地址,IPV4那一行.如:1 ...

  3. 用python快速开发一个实用的socket服务器

    用python快速开发一个实用的socket服务器 - 吴尔平 - 博客园 用python快速开发一个实用的socket服务器 首先,要明白不是所有的socket服务都需要高性能.如果要求高性能,使用 ...

  4. java开发plc上位机软件开发_上位机开发之西门子PLC-S7通信实践

    写在前面: 就目前而言,在中国的工控市场上,西门子仍然占了很大的份额,因此对于上位机开发而言,经常会存在需要与西门子PLC进行通信的情况.然后对于西门子PLC来说,通信方式有很多,下面简单列举一下: ...

  5. python连接linux堡垒机_利用Python Paramiko开发linux堡垒机

    1.Paramiko模块下的demo.py程序 前面利用Python中的Paramiko模块可以进行SSH的连接,以及用来传送文件(SFTP),但是无论是哪一种方式,连接都是短暂的,并非是长连的,即一 ...

  6. 如何用 Python 快速开发一个区块链数据结构?

    作者 | arjuna sky kok 整理 | Aholiab 出品 | 区块链大本营(blockchain_camp) 根据IEEE此前的一项调查,Python已成为最受开发者欢迎的语言之一.由于 ...

  7. python自动点名程序_利用python+tkinter开发一个点名软件

    from win32com.client importDispatchfrom tkinter import * importtkinter as tkfrom PIL importImagefrom ...

  8. python自动垃圾分类_现在垃圾都得分类,如何利用Python快速实现一个垃圾分类APP?...

    最近北京开始实行垃圾分类,导致大家对垃圾的研究热度突然涨高,垃圾们也纷纷表示从来没有获得过这么高的关注度.其实,上海市去年已经开始实行,网上已经有不少成熟的教程了,像什么<垃圾分类从入门到精通& ...

  9. 利用python快速搭建一个ftp文件服务器

    点击上方"AI搞事情"关注我们 前置条件:python环境 一行命令 python -m http.server 端口号 # python3 python -m SimpleHTT ...

最新文章

  1. Python OpenCV 图片拆分与拼接
  2. VS2010解决方案位置不对和改变程序字体的方案
  3. PrepareStatement 和Statement 的区别?
  4. python字符串解析_Python-字符串解析-正则-re
  5. Mysql yum 安装后,一些重要的文件路径
  6. java主动对象模式_POCO的主动对象
  7. 中国喷淋泵行业市场供需与战略研究报告
  8. 无法将该对象添加到ldap服务器_Minecraft 基岩版 Ubuntu服务器搭建(三)
  9. 多易教育大数据课程学费调整通知
  10. 计算机管理的服务打不开,Windows 系统服务无法打开解决方法+操作命令详解
  11. Facebook 应用开发认证和授权登录流程
  12. [论文总结] 科技论文英语写作笔记1
  13. 小程序页面浏览到底部触发事件
  14. 投资黄金,当然选贸易场行员平台真宝金业,安全有保障,返佣高,平仓返。
  15. 计算机组成原理 原码,反码,补码,移码
  16. CCS3.3 新建工程遇到的问题
  17. Serial Programming Guide for POSIX Operating Systems
  18. css背景透明(css背景透明度怎么设置)
  19. 前端的岗位以及初步了解
  20. Validator框架的使用

热门文章

  1. Flex Builder3调试运行提示没有安装Flash Player
  2. 今夕何夕(思路详解)
  3. 2-Pyridinylacetic acid,2-吡啶基乙酸,CAS号:13115-43-0
  4. 物联网开发笔记(80)- 使用Micropython开发ESP32开发板之通过IIC接口控制TM1650四位共阴数码管模块
  5. 怎么解密PDF文档?这三款解密方法亲测实用
  6. Vue 点击按钮跳转其他链接
  7. 校友会小程序开发笔记四:UI基本元素设计
  8. 前端(js/css/html)那些小的知识点,持续更新......
  9. 校招 | 微软萌新记:实习初体验
  10. 3d动画用云渲染靠谱吗?