(详细分析)python PyQt5图形界面编程(含pyqtgraph画3D散点图、父子窗口间传递信息、pyinstaller打包可执行exe文件)

本文主要是介绍(详细分析)python PyQt5图形界面编程(含pyqtgraph画3D散点图、父子窗口间传递信息、pyinstaller打包可执行exe文件),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

介绍

 layout

制作应用程序,pyinstaller

单选框

tab页中布局

显示样式

画3D散点图

子窗口与父窗口信息交互


  • 介绍

    • 网站http://www.python3.vip/tut/py/gui/qt_09/
    • Tkinter、wxPython、PySide2、PyQt5
    • 按住Ctrl拖动控件,直接复制
  •  layout

    • sizepolicy控件大小
    • 按住Ctrl键拖动就是复制
    • 调整layout中控件的大小比例,优先使用layout的layoutStrentch属性来控制
    • 把控件挤小,可使用horizontal spacer
  • 制作应用程序,pyinstaller

    • 打包完之后会有两个文件夹build和dist,build不用管,dist里的是你需要的exe文件及相关东西。
    • 注意运行的时候,若代码编写时使用的静态加载(load)方法加载的UI文件,使用pyinstaller打包完后,需要把ui文件拷贝到生成的可执行文件中,不然会报错。
    • 举例:命令行中运行pyinstall httpclient.py --noconsole --hidden-import PySide2.QtXml
      • 其中--noconsole指运行exe时不出现调试窗口(类似于你直接在pycharm中run后,显示错误的底部的4:run窗口)。如果要测试,可以去掉该命令,从而保留调试窗口,出现的错误会在该窗口中显示。--hidden-import PySide2.QtXml是因为这个QtXml库是动态导入,需要我们告诉PyInstaller,不然运行exe文件后,会在调试窗口中报错:No module named XXXX
    • # 添加主窗口图标(打开EXE之后左上角显示的图标
      # from PySide2.QtGui import QIcon
      #
      # app = QApplication([])
      # # 加载icon
      # app.setWindowIcon(QIcon('logo.png'))# 应用程序图标,打包成的exe文件的图标
      # 制作程序的时候,写上
      # pyinstaller httpclient.py --noconsole --hidden-import PySide2.QtXml --icon="logo.ico"
      # 注意参数一定是.ico文件,不能使png等图片文件,可以通过在线的png转ico文件网站,生成ico
      # 比如https://www.zamzar.com/convert/png-to-ico/或者https://www.easyicon.net/covert/
    • 使用pyinstaller过程中遇到的问题及解决办法:
      • https://blog.csdn.net/weixin_42052836/article/details/82315118(Pyinstaller 打包发布经验总结)
      • https://blog.csdn.net/qq_38232378/article/details/95767597?utm_medium=distribute.pc_relevant.none-task-blog-title-2&spm=1001.2101.3001.4242(解决PyInstaller vcruntime140.dll没有被指定在Windows上运行)
      • 命令(生成单个程序,附带图标,生成在指定文件夹,使用upx压缩)
      • pyinstaller -F C:\Users\levovozzb\Desktop\bag\sp.py --distpath=C:\Users\levovozzb\Desktop\bag -i C:\Users\levovozzb\Desktop\bag\cs.ico --upx-dir=D:\ThunderDownload\upx-3.96-win64\upx.exepyinstaller -F 待打包py文件路径  ----distpath=程序指定生成的文件夹路径  -i  图标ico地址  --upx-dir=程序upx.exe的存放路径upx的下载网址:https://github.com/upx/upx/releases/tag/v3.95

         

      • 若使用upx进行打包,upx is not avaliable报错
        • 解压安装包得upx.exe文件,将exe拷贝到pyinstaller目录下,我的是E:\anaconda\Scripts
        • 虚拟纯python环境中,放的是C:\Users\qq154\.virtualenvs\htkjproject-9aXzGckk\Scripts
      • 查看第三方包版本号pip list或者pip show XXX
      • 安装特定版本的第三方包pip install XXX==5.15.0
      • 苦苦处理两周的问题终于解决了。通过把相关包位置加到系统环境变量中或者直接都打包进去是最有效果的。简单粗暴,之后再慢慢的缩减不需要的包即可。我的问题是通过在.spec文件中处理,再打包解决的。流程如下:
      • a = Analysis(['Client.py'],pathex=['E:\\PyCharm 2019.1.2\\pycharmprojects\\htkjproject', 'E:\\anaconda\\Lib\\site-packages\\PyQt5\\Qt\\bin', 'E:\anaconda\Lib\site-packages', 'E:\anaconda\Lib\site-packages\PyQt5', 'E:\anaconda\Lib\site-packages\pyqtgraph'],binaries=[],datas=[],hiddenimports=['PyQt5.QtOpenGL'],hookspath=[],runtime_hooks=[],excludes=[],win_no_prefer_redirects=False,win_private_assemblies=False,cipher=block_cipher,noarchive=False)# 打包出来的有290M(落泪.jpg),慢慢删减之后再更

         

      • 另外,如果使用anaconda的集成python环境,一般打出来的包会很大。。。。解决方式https://www.zhihu.com/question/268397385?sort=created( 用pipenv创建纯python的虚拟环境),https://blog.csdn.net/frostime/article/details/90523062(此在虚拟环境中,也可以直接pip安装,用pipenv install安装第三方包要检查,太慢,因此推荐pip install)
      • 在解决包很大的过程中,尝试在虚拟纯python环境中打包遇到问题:
      • “could not find or load the Qt platform plugin ”windows", this application failed to start because no qt platform plugin could be initialized

      • 发现当把环境变量中的QT_QPA_PLATFORM_PLUGIN_PATH设置为虚拟环境中pyqt5的plugins路径就可以运行,具体原因尚未清楚。而且显然这样对软件的可移植性有很大限制。换台主机就要配置变量是一件很Emm的事情。。。https://www.thetopsites.net/article/50550987.shtml
        • oh,终于解决了。参考https://stackoverflow.com/questions/47468705/pyinstaller-could-not-find-or-load-the-qt-platform-plugin-windows中回答的办法,不用管环境变量了,copying the ~PyQt5\Qt\plugins\platforms folder from the program's directory, generated by using pyinstaller --onedir main.py, to the folder holding the .exe file.即可
      • 总而言之,我在项目中解决文件过大的过程为:
      • # 在命令行中输入# 先基于对应版本的python生成虚拟python环境
        pipenv install --python 3.7# 启动虚拟环境
        pipenv shell# 安装pyinstaller
        pip install pyinstaller# 安装UI所需的包
        pip install pyopengl
        pip install pyqtgraph
        ...# 安装完之后打包
        pyinstaller -F client.py
        # -F选项为生成一个文件,会保留调试窗,若不想保留可以使用-Fw# 运行生成的.exe,根据调试窗的问题完善代码。若有其他问题可以在.spec文件中修改之后,使用如下语句打包:
        pyinstaller -F client.spec

         

  • 单选框

    • 同一组的按钮,Ctrl多选右键button group建立新的按钮组
  • tab页中布局

    • tab widget中的tab布局,直接右键是没有layout选项的,要在他右上角的对象的框 的上层tabwidget右键才有layout
  • 显示样式

    • 参考http://www.python3.vip/tut/py/gui/qt_09/
    • QSS类似于CSS,
    • 根据object(ID)修改,语言加#,根据class选不加
    • 选中最上mainwindow,下面属性中有个stylesheet,点一下,选三个点,输入样式代码
    • selector,与webcss的语法基本没区别。
    •  字体font-family,大小font-size,颜色color
    •  qt修改style之后有个bug,得去掉style代码之后,重新输入正确的
    • flat勾选之后,按钮的边框就不见了
    • 可以自己加动态属性,在property下面的框选加号,一般选string,然后选择性的控制部分控件的style
    • 修改某控件内部,比如tabwidget的内容的字体颜色,#tabWidget * {\n    color:red\n}
      • 若只修改直接子节点的style,则#tabWidget > * {}
      • 空格是内部的所有
    • 调色,alpha通道是调透明度
    • Pseudo-States伪状态
      • QPushButton:hover {color: red} hover悬浮,鼠标放到此位置时变化
      • disable状态,:disabled
      • 鼠标悬浮并且处于勾选checked状态,:hover:checked
      • QPushButton:hover{font-family:微软雅黑;font-size:15px;color: #1d649c;}

         

    • 指定背景色,background-color,背景图片background-image

    • 边框

    • 间隔,对外的margin四个就上右下左,顺时针,从上开始,也可margin-top,元素内容到内边框的边界为padding

    • 优先级
      • 越靠近的style优先级越高,可直接针对对象修改style
      • 样式官方文档https://doc.qt.io/qt-5/stylesheet-reference.html#list-of-properties
    • 多线程后台任务
      • 遇到较耗时的任务时,最好创建新的子线程去执行,避免主线程阻塞
      • 把要实现的功能做成函数,然后t = Thread(target=run)    t.start()
    • 第三方画图控件plotwidget载入,https://www.bilibili.com/video/av78483752?p=3
      • 用widget占个位,右键promote,提升类,类名即PlotWidget,头文件为其所在的库,即from 头文件 import PlotWidget
      • 注意没有core,图中仅举例
    • 导入文件(即load)时,pyside2要比pyqt5多个注册,即在loader.load(“main.ui”)前loader.registerCustomWidget(pg.PlotWidget)。即要把PlotWidget从哪儿来的要注册一下
    •  轴刻度为字符串功能,获取鼠标所在处刻度值
      • http://www.python3.vip/tut/py/gui/pyqtgraph-2/
    • 内嵌web浏览器
      •  
    •  将ui文件转换为python代码,pycharm中选中ui文件,最上栏tools-external tools选择pyUIC,即完成
  • 画3D散点图

    • 详细的示例分析见:
      • https://blog.csdn.net/qq_38025771/article/details/109896143
    • 需要采用的
      • pyqtgraph.opengl
      • opengl中的GLViewWidget
    • pyqtgraph功能强大,使用pip安装好后,可以在命令行中运行下行代码,查看pyqtgra图例
      • python -m pyqtgraph.examples
    • 推荐资料
      • https://zmister.com/archives/187.html(做了解用)
      • https://blog.csdn.net/API1_7/article/details/98249965(画图需要使用定时器,多线程,建议单独线程画图)
    • 采用普通widget升级(promote)到GLViewWidget
    • #设置最小化与最大化按钮
      self.setWindowFlags(QtCore.Qt.Window)
    •  UI布局文件:
    • # NodeStatus.py
      from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_NodeStatus(object):def setupUi(self, NodeStatus):NodeStatus.setObjectName("NodeStatus")NodeStatus.resize(695, 401)sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(NodeStatus.sizePolicy().hasHeightForWidth())NodeStatus.setSizePolicy(sizePolicy)NodeStatus.setStyleSheet("*{    \n""    font-family:微软雅黑;\n""    font-size:15px;\n""    color: #1d649c;\n""}\n""")self.verticalLayout = QtWidgets.QVBoxLayout(NodeStatus)self.verticalLayout.setObjectName("verticalLayout")self.guiplot = GLViewWidget(NodeStatus)self.guiplot.setObjectName("guiplot")self.guiplot.opts['distance'] = 50  # 设置初始镜头高度self.verticalLayout.addWidget(self.guiplot)self.retranslateUi(NodeStatus)QtCore.QMetaObject.connectSlotsByName(NodeStatus)def retranslateUi(self, NodeStatus):_translate = QtCore.QCoreApplication.translateNodeStatus.setWindowTitle(_translate("NodeStatus", "节点状态"))from pyqtgraph.opengl import GLViewWidget
      
    • 主文件中画图进程类和子窗口(显示3d散点图)类
    • from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog
      from PyQt5.QtCore import QThread, pyqtSignal, QTimer, Qt
      from PyQt5 import uic
      import pyqtgraph.opengl as gl
      import numpy as npclass PlotNode(QThread):'''给予画图多线程提供点数据分析功能'''signal = pyqtSignal(object, object, object, object)  # 定义信号,根据信息交互设置参数位def __init__(self):super(PlotNode, self).__init__()self.nodeStatus = {}def plotNodeStatus(self):'''初始化画散点图所需的点数据:position,size,color:return:'''self.distance = 0  # 用于3D图的视角高度设定self.num = self.nodeStatus['num_nodes']self.x = self.nodeStatus['x']self.y = self.nodeStatus['y']self.z = self.nodeStatus['z']self.running = self.nodeStatus['running']self.malicious = self.nodeStatus['malicious']# 设置numpy.ndarray类型的数据,用于画散点图self.pos = np.empty((self.num, 3))self.size = np.empty((self.num))self.color = np.empty((self.num, 4))for i in range(self.num):self.pos[i] = (self.x[i], self.y[i], self.z[i])max_num = max(self.x[i], self.y[i], self.z[i])if abs(self.distance) < abs(max_num):self.distance = abs(max_num)self.size[i] = 0.5if self.running[i] == True and self.malicious[i] == False:self.color[i] = (0.0, 1.0, 0.0, 0.5)  # 绿色elif self.malicious[i] == True:self.color[i] = (1.0, 0.0, 0.0, 0.5)  # 红色else:self.color[i] = (1, 1, 1, 0.5)  # 灰色QThread.msleep(100)  # 等待100毫秒def run(self):for _ in range(300):self.plotNodeStatus()self.signal.emit(self.distance, self.pos, self.size, self.color)  # 向连接槽发射信号 self.yclass ChildWinNodeStatus(QDialog, Ui_NodeStatus):def __init__(self):super(ChildWinNodeStatus, self).__init__()self.setupUi(self)# 设置窗口最小化与最大化按钮self.setWindowFlags(Qt.Window)def child_plotNode(self, distance, pos, size, color):self.guiplot.clear()g = gl.GLGridItem()size_axes = distance * 3g.setSize(x=size_axes, y=size_axes, z=size_axes)self.guiplot.addItem(g)sp = gl.GLScatterPlotItem(pos=pos, size=size, color=color, pxMode=False)self.guiplot.addItem(sp)

       

  • 子窗口与父窗口信息交互

    • 建议写好子窗口的相关功能,在父窗口中对子窗口的内容进行相关操作。
    • 相关资料:
      • https://blog.csdn.net/API1_7/article/details/98249965(PyQt/PySide2 中的 信号与槽 (pyqtSignal/Signal) 、多线程 (QThread) 和 定时器 (Timer))
      • https://github.com/binghan523/pyqt_fatherAndChildSignalCommunication/tree/master/pyqt_fatherAndChildSignalCommunication/pyqt_fatherAndChildSignalCommunication(子窗口与父窗口之间互相发送接收消息)
    • 重点知识:
      • 类与类之间信息触发采用pyqtsignal,且注意设置的参数个数与要传的参内容一致。signal.connect(func)绑定信号发送后触发的函数
      • from PyQt5.QtCore import pyqtSignalsignal = pyqtSignal(object, object, object, object)  # 定义信号,根据信息交互设置参数位,objetct是通用格式# 主窗口中某函数,绑定def ui_plotStatus_child(self, nodeStatus):'''接收到节点数据后,在子窗口上画图'''self.plot_thread.nodeStatus = nodeStatusself.plot_thread.signal.connect(self.ChildUI_NodeStatus.child_plotNode)self.plot_thread.start()# self.plot_thread是在主窗口中提前实例化的PlotNode类对象

         

      • 在父窗口中,要先初始化一个子窗口的实例,当要打开子窗口时,让实例.show()即可
      • self.ChildUI_NodeStatus = ChildWinNodeStatus()self.ChildUI_NodeStatus.show()

         

      • 在主窗口的函数中对子窗口实例进行操作。
  • 常见问题解决方法

    • 若某按钮被点击动作为打开新的子窗口,且该按钮cliced绑定函数A,若在A函数外调用窗口.show()方法,UI会卡死。
      • 解决:当需要在A函数外打开该子窗口,则可写一句该button.clicked(),即相当于按钮被点击。不会卡死。

 

pyqt5开发过程关键问题总结


[点击查看](https://blog.csdn.net/qq_38025771/article/details/109675990)

 

 

 

 

 

 

 

 

 

 

 

 

这篇关于(详细分析)python PyQt5图形界面编程(含pyqtgraph画3D散点图、父子窗口间传递信息、pyinstaller打包可执行exe文件)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/180741

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

springboot3打包成war包,用tomcat8启动

1、在pom中,将打包类型改为war <packaging>war</packaging> 2、pom中排除SpringBoot内置的Tomcat容器并添加Tomcat依赖,用于编译和测试,         *依赖时一定设置 scope 为 provided (相当于 tomcat 依赖只在本地运行和测试的时候有效,         打包的时候会排除这个依赖)<scope>provided

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

nudepy,一个有趣的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - nudepy。 Github地址:https://github.com/hhatto/nude.py 在图像处理和计算机视觉应用中,检测图像中的不适当内容(例如裸露图像)是一个重要的任务。nudepy 是一个基于 Python 的库,专门用于检测图像中的不适当内容。该

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip