0
点赞
收藏
分享

微信扫一扫

【Python笔记】pyqt5窗体程序制作流程

沐之轻语 2022-05-02 阅读 43

目录

主要功能

环境配置

窗体程序必需:

(非必需)打包程序配置:

代码实现

1、设计UI

2、窗体代码编译生成

3、运行程序

 程序打包


主要功能

 pyqt5窗体程序设计实践,简述大致流程:包括环境设置、界面设计、程序运行和打包等

环境配置

主要版本如下:

python 3.9.7

PyQt5 5.15.6

GDAL 3.4.1

numpy 1.22.3

pandas 1.4.2

pyinstaller 5.0

窗体程序必需:

建议安装conda创建新的虚拟环境,然后配置到pycharm,便于后续应用

  1. 新建环境:conda create -n name python=3.9  name换成自定义的英文名 
  2. 激活环境:conda activate name 安装所需的包
  3. pip install PyQt5
    pip install pyqt5-tools
    pip install GDAL-3.4.1-cp39-cp39-win_amd64.whl
    此处pip在线安装模式错误,下载对应版本的GDAL whl文件,切换到到文件所在目录执行此命名安装,下载网址:Python Extension Packages for Windows - Christoph Gohlke (uci.edu) 可在该网页按ctrl+F 找到gdal
    pip install numpy
    pip install pandas
    pip install pyinstaller
  4. 配置到pycharm,选择新建环境的路径
  5. 配置快捷工具 添加前面虚拟环境的对应路径:本路径为E:\ProgramData\Anaconda3\envs\qt39\Lib\site-packages\qt5_applications\Qt\bin\designer.exe仅供参考,自行修改。项目路径:$ProjectFileDir$参考路径:E:\ProgramData\Anaconda3\envs\qt39\python.exe 占位运算符命令-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py 指向项目文件夹下ui文件夹$ProjectFileDir$\ui 后续将ui文件保存在里面

(非必需)打包程序配置:

前面创建的环境中打包,可直接进行打包操作,可是conda环境中打包可能会体积较大,所以安装pipenv虚拟环境拓展包,配置轻量的python虚拟环境进行打包

  1. 安装 pip install pipenv
  2. 事先新建并进入项目文件夹中,创建虚拟环境 pipenv --python 3.9 指定python版本为3.9
  3. 进入虚拟环境 pipenv shell
  4. 安装拓展包(可不必安装pyqt5-tools开发工具)
    pip install PyQt5
    pip install pyqt5-tools
    pip install GDAL-3.4.1-cp39-cp39-win_amd64.whl
    pip install numpy
    pip install pandas
    pip install pyinstaller
  5. 退出虚拟环境 exit

 

代码实现

1、设计UI

        菜单栏 Tools >External Tools > designer 打开designer

a)新建文件

 b)左侧工具栏选择控件 添加到界面

c) 保存ui文件

将*.ui文件保存到项目的ui文件夹下,便于使用拓展工具转化为需要的py文件

日期格式转换.ui文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>475</width>
    <height>147</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>日期格式转换</string>
  </property>
  <widget class="QDateEdit" name="dateEdit">
   <property name="geometry">
    <rect>
     <x>350</x>
     <y>30</y>
     <width>81</width>
     <height>22</height>
    </rect>
   </property>
   <property name="displayFormat">
    <string>yyyy-M-d</string>
   </property>
  </widget>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>350</x>
     <y>10</y>
     <width>54</width>
     <height>12</height>
    </rect>
   </property>
   <property name="text">
    <string>距参考日</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>350</x>
     <y>80</y>
     <width>81</width>
     <height>21</height>
    </rect>
   </property>
   <property name="text">
    <string>转换</string>
   </property>
  </widget>
  <widget class="QLabel" name="label_2">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>10</y>
     <width>54</width>
     <height>12</height>
    </rect>
   </property>
   <property name="text">
    <string>选择文件:</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="lineEdit">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>30</y>
     <width>281</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QLabel" name="label_4">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>60</y>
     <width>54</width>
     <height>12</height>
    </rect>
   </property>
   <property name="text">
    <string>输出路径:</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="lineEdit_2">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>80</y>
     <width>281</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

2、窗体代码编译生成

*.ui文件转换为*.py文件,在ui文件夹下右键>External Tools>PyUIC,借助前文配置的转化工具转化

 生成的py文件(日期格式转换.py)内容如下:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '日期格式转换.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(475, 147)
        self.dateEdit = QtWidgets.QDateEdit(Dialog)
        self.dateEdit.setGeometry(QtCore.QRect(350, 30, 81, 22))
        self.dateEdit.setObjectName("dateEdit")
        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(350, 10, 54, 12))
        self.label.setObjectName("label")
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(350, 80, 81, 21))
        self.pushButton.setObjectName("pushButton")
        self.label_2 = QtWidgets.QLabel(Dialog)
        self.label_2.setGeometry(QtCore.QRect(30, 10, 54, 12))
        self.label_2.setObjectName("label_2")
        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        self.lineEdit.setGeometry(QtCore.QRect(30, 30, 281, 21))
        self.lineEdit.setObjectName("lineEdit")
        self.label_4 = QtWidgets.QLabel(Dialog)
        self.label_4.setGeometry(QtCore.QRect(30, 60, 54, 12))
        self.label_4.setObjectName("label_4")
        self.lineEdit_2 = QtWidgets.QLineEdit(Dialog)
        self.lineEdit_2.setGeometry(QtCore.QRect(30, 80, 281, 21))
        self.lineEdit_2.setObjectName("lineEdit_2")

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "日期格式转换"))
        self.dateEdit.setDisplayFormat(_translate("Dialog", "yyyy-M-d"))
        self.label.setText(_translate("Dialog", "距参考日"))
        self.pushButton.setText(_translate("Dialog", "转换"))
        self.label_2.setText(_translate("Dialog", "选择文件:"))
        self.label_4.setText(_translate("Dialog", "输出路径:"))

3、运行程序

py文件(日期格式转换.py)已经编译出来,但并不能运行,因为PyUIC只会生成在designer中定义的东西,还需要加入程序入口的代码。
这里另起一个py文件(main日期格式转换.py)作为程序入口和业务逻辑的实现,这样就可以实现UI和业务逻辑分离,修改了UI重新生成不会将之前的py文件全部覆盖,便于修改
我的py文件(main日期格式转换.py)代码如下:
注意:import刚才生成的py文件名称,我这里是“日期格式转换”,根据情况替换;

a)MyWindow对象继承Pyqt5拓展包内的QDialog和py文件(日期格式转换.py)内的Ui_Dialog

b)初始化函数内进行前端后台的连接:self.dateEdit.dateChanged.connect(self.onDateChanged)为日期框(名称为dateEdit)设置监听事件onDateChanged;self.pushButton.clicked.connect(self.zhuanhuan)为按钮(名称为pushButton)设置点击事件zhuanhuan;QAction定义一个图标,可设置图标,借助act.triggered.connect(self.wenjian)绑定槽函数wenjian;此外pyqt5还有很多的控件以及交互事件;

c)实例化MyWindow对象为myWin,myWin.show()显示窗体

import sys
from datetime import datetime
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import *
from 日期格式转换 import *

class MyWindow(QDialog, Ui_Dialog):
    def __init__(self):
        super(MyWindow, self).__init__()
        self.setupUi(self)

        self.maindata = {}

        self.maindata["date"] = self.dateEdit.text()
        self.maindata["date"] = datetime.strptime(self.maindata["date"], '%Y-%d-%m')
        self.dateEdit.dateChanged.connect(self.onDateChanged)

        act = QAction(self)  # 定义一个行为
        act.setIcon(QIcon('image/编辑文件.png'))  # 设置行为icon,
        act.triggered.connect(self.wenjian)  # 绑定行为槽函数
        self.lineEdit.addAction(act, QLineEdit.TrailingPosition)  # 将该行为添加到lineEdit最右端

        act2 = QAction(self)  # 定义一个行为
        act2.setIcon(QIcon('image/select.png'))  # 设置行为icon,
        act2.triggered.connect(self.outdir)  # 绑定行为槽函数
        self.lineEdit_2.addAction(act2, QLineEdit.TrailingPosition)  # 将该行为添加到lineEdit最右端

        self.pushButton.clicked.connect(self.zhuanhuan)

    def onDateChanged(self):
        self.maindata["date"] = datetime.strptime(self.dateEdit.text(), '%Y-%d-%m')

    def outdir(self):
        self.maindata["outPath"] = QFileDialog.getExistingDirectory(None, "输出文件夹", "C:/")  # 返回选中的文件夹路径
            # QFileDialog.getOpenFileName()  # 返回选中的文件路径
            # QFileDialog.getOpenFileNames()  # 返回选中的多个文件路径
            # QFileDialog.getSaveFileName()  # 存储文件
        self.lineEdit_2.setText((QtCore.QCoreApplication.translate("tile", self.maindata["outPath"])))
        print(self.maindata)

    def wenjian(self):

        self.maindata["wenjian"] = QFileDialog.getOpenFileName(None,"选取文件","C:/","CSV文件(*.csv)")
            # 返回选中的文件夹路径
        if(self.maindata["wenjian"][0]==""):
            return
        self.maindata["wenjian"]=self.maindata["wenjian"][0]
        pathMixName = self.maindata["wenjian"].split('/')  # 将fn按照/切分
        pathx = "/".join(pathMixName[0:len(pathMixName) - 1])  # 假设切分后有n部分,将前n-1部分用/重新拼接,就是文件的路径
        namex = pathMixName[len(pathMixName) - 1]  # 最后一个就是文件名
        print(pathx,namex)
        self.maindata["wenjianname"]=namex
        self.lineEdit.setText(self.maindata["wenjian"])

        print(self.maindata)

    def zhuanhuan(self):
        print(self.maindata)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    myWin = MyWindow()
    myWin.show()

    sys.exit(app.exec_())

d)窗体结果

 程序打包

可直接在conda虚拟环境中打包,移动到py文件所在目录,打包方式主要有两种1)打包成一个exe:pyinstaller -w -F 日期格式转换.py 刚才生成的py文件名称,我这里是“日期格式转换”,根据情况替换;2)打包成文件目录pyinstaller -w 日期格式转换.py 速度较快,体积较大。

注意:打包完成后会在dist文件夹,-w为窗体程序,运行时关闭控制台;image等资源需要手动复制,1)为exe同路径、2)为dist下程序文件内;

若需要打包成更小体积的程序,就需要配置前文的 “(非必需)打包程序配置”,激活虚拟环境后移动到py文件所在目录,后续步骤相同

举报

相关推荐

0 条评论