古之成大事者,不惟有超士之才,亦唯有坚韧不拔之志

Mac配置PyQt5+pyCharm并使用

最近想用python写一个GUI程序,主要是工作中有时会需要,便想着工具化,节省效率,也可以给团队使用,中间踩了无数坑,百度+google了很多,有些依旧找不到答案,但是程序出来后还是很欢喜的。找了下python的GUI框架,最后选择了PyQt5。本篇文章主要介绍一下如何配置安装到最后打包使用。

一、环境的配置

系统:mac

Python版本:python3.75

Qt:5.13.2(最新版)

Pyqt5:最新版

1、安装所需的软件和库

分别在终端输入下边三条命令执行即可。(pycharm和python的安装就不细说了,非常简单的常用操作,能使用pyqt5的,一般这两个都准备好了)

  1. 安装Qt
  2. 安装PyQt5库
  3. 安装sip库(对于作者来说,不知道干嘛的,但是少了就有问题,照着做就行)
brew install qt
pip3 install pyqt5
pip3 install sip

上边命令执行完毕后,基本安装就结束了。

2、配置pyCharm开发环境(这里主要是和pyqt5结合起来)

下边我们配置三个东西:desigener(设计器),uic(把设计文件转化为py文件),qrc(把样式文件转化为样式文件)

第一步:我们配置一下打开pyqt5的designer

《Mac配置PyQt5+pyCharm并使用》

name:Py_Designer(自定义)
program:/usr/local/Cellar/qt/5.13.2/libexec/Designer.app(根据自己的来)
diretory:$FileDir$

第二步:配置pyuic

《Mac配置PyQt5+pyCharm并使用》

name:Py_Uic(自定义) 
program:/usr/local/bin/python3(根据自己的来) 
Arguments:-m PyQt5.uic.pyuic  $FileName$ -o $FileNameWithoutExtension$.py(转化脚本)
diretory:$FileDir$

第三步:配置Qrc(这一步找了好久,自己摸索出来了,找不到pyrcc这个东西,但是有其他的可以使用

《Mac配置PyQt5+pyCharm并使用》

name:Py_Qrc(自定义) 
program:/usr/local/bin/python3(根据自己的来) 
Arguments:-m PyQt5.pyrcc_main $FileName$ -o $FileNameWithoutExtension$_rc.py(转化脚本) 
diretory:$FileDir$

这里很重要哦,用的是PyQt5.pyrcc_main。。配置完成后就是下图。

《Mac配置PyQt5+pyCharm并使用》

开始测试一下:

1,desigener

《Mac配置PyQt5+pyCharm并使用》

2,转化为py文件

《Mac配置PyQt5+pyCharm并使用》

点一下,会发现生成了一个同名的py文件

3,转化qrc为py文件

同理,选中文件,使用刚才配置的Py_Qrc即可

《Mac配置PyQt5+pyCharm并使用》

二、程序的设计

基础配置后,我们来尝试一个例子,做一个视频下载器,里边使用python的you-get库。

下边我们设计一个界面:

在qdesigner中托拽空间即可,其中每个空间的名称需要记住,后边需要使用槽和信号来编辑逻辑执行文件。

《Mac配置PyQt5+pyCharm并使用》

我们可以在编辑器中使用样式文件,如果有图片等附件,会生成一个qrc文件。

《Mac配置PyQt5+pyCharm并使用》

界面设置完成后,我们执行UI为py文件,qrc为py文件,即目录如图:

《Mac配置PyQt5+pyCharm并使用》

其中UI转化的py为代码为:

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

# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(485, 430)
        Form.setMaximumSize(QtCore.QSize(485, 430))
        Form.setStyleSheet("")
        self.verticalLayoutWidget = QtWidgets.QWidget(Form)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(20, 20, 451, 46))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
        font = QtGui.QFont()
        font.setPointSize(20)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label, 0, QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
        self.verticalLayoutWidget_2 = QtWidgets.QWidget(Form)
        self.verticalLayoutWidget_2.setGeometry(QtCore.QRect(20, 100, 451, 71))
        self.verticalLayoutWidget_2.setObjectName("verticalLayoutWidget_2")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_2)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.label_2 = QtWidgets.QLabel(self.verticalLayoutWidget_2)
        self.label_2.setObjectName("label_2")
        self.verticalLayout_2.addWidget(self.label_2)
        self.line1 = QtWidgets.QLineEdit(self.verticalLayoutWidget_2)
        self.line1.setObjectName("line1")
        self.verticalLayout_2.addWidget(self.line1)
        self.horizontalLayoutWidget = QtWidgets.QWidget(Form)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 190, 451, 41))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.btn1 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.btn1.setObjectName("btn1")
        self.horizontalLayout.addWidget(self.btn1)
        self.line2 = QtWidgets.QLineEdit(self.horizontalLayoutWidget)
        self.line2.setObjectName("line2")
        self.horizontalLayout.addWidget(self.line2)
        self.label_3 = QtWidgets.QLabel(Form)
        self.label_3.setGeometry(QtCore.QRect(30, 240, 341, 16))
        self.label_3.setStyleSheet("color: rgb(150, 153, 153);")
        self.label_3.setObjectName("label_3")
        self.btn2 = QtWidgets.QPushButton(Form)
        self.btn2.setGeometry(QtCore.QRect(160, 280, 151, 41))
        self.btn2.setStyleSheet("background-color: rgb(89, 94, 255);\n"
"font: 14pt \"Kaiti SC\";")
        self.btn2.setObjectName("btn2")
        self.line = QtWidgets.QFrame(Form)
        self.line.setGeometry(QtCore.QRect(170, 60, 151, 16))
        self.line.setFrameShape(QtWidgets.QFrame.HLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.line_2 = QtWidgets.QFrame(Form)
        self.line_2.setGeometry(QtCore.QRect(20, 170, 451, 16))
        self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_2.setObjectName("line_2")
        self.line_3 = QtWidgets.QFrame(Form)
        self.line_3.setGeometry(QtCore.QRect(20, 260, 451, 16))
        self.line_3.setFrameShape(QtWidgets.QFrame.HLine)
        self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line_3.setObjectName("line_3")
        self.label_4 = QtWidgets.QLabel(Form)
        self.label_4.setGeometry(QtCore.QRect(30, 330, 441, 78))
        self.label_4.setObjectName("label_4")
        self.widget = QtWidgets.QWidget(Form)
        self.widget.setGeometry(QtCore.QRect(-1, -1, 491, 431))
        self.widget.setStyleSheet("\n"
"background-image: url(:/Users/leif/PycharmProjects/v_down/images/timg.png);\n"
"")
        self.widget.setObjectName("widget")
        self.widget.raise_()
        self.verticalLayoutWidget.raise_()
        self.verticalLayoutWidget_2.raise_()
        self.horizontalLayoutWidget.raise_()
        self.label_3.raise_()
        self.btn2.raise_()
        self.line.raise_()
        self.line_2.raise_()
        self.line_3.raise_()
        self.label_4.raise_()

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.label.setText(_translate("Form", "全网视频下载神器"))
        self.label_2.setText(_translate("Form", "将您要下载的视频网址粘贴到下方(必须得有哦)"))
        self.btn1.setText(_translate("Form", "请选择存储目录"))
        self.label_3.setText(_translate("Form", "备注:若您不选择目录,则自动下载在当前目录下"))
        self.btn2.setText(_translate("Form", "开始下载"))
        self.label_4.setText(_translate("Form", "小提示:下载过程中会有卡顿问题,不关注即可,下载完成后自动退出"))
import css_rc

 

编写的逻辑文件如下,就不详细解释了

import sys, os
from untitled import Ui_Form
from PyQt5.QtWidgets import *
import you_get
from PyQt5.QtCore import *



def download(url, path):
    sys.argv = ['you-get', '-o', path, url]
    you_get.main()


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.setWindowTitle('视频下载器')
        # 设置信号、槽
        self.ui.btn2.clicked.connect(self.getUrl)
        self.ui.btn1.clicked.connect(self.dir)
        self.statusBar().showMessage('版本:v0.1 -- 作者邮箱:admin@tyty.xyz')


    def dir(self):
        directory = QFileDialog.getExistingDirectory(self, "选取文件夹", "./")  # 起始路径
        print(directory)
        self.ui.line2.setText(directory)

    def getUrl(self):
        url = self.ui.line1.text()
        path = self.ui.line2.text()
        if not path:
            path = os.getcwd()
        print(path)
        if not url:
            dialog = QDialog()
            # 创建按钮到新创建的dialog对象中
            text = QLabel("没有输入地址哦", dialog)
            # 移动按钮,设置dialog的标题
            text.move(50, 50)
            dialog.setWindowTitle("小提示")
            # 设置窗口的属性为ApplicationModal模态,用户只有关闭弹窗后,才能关闭主界面
            dialog.setWindowModality(Qt.ApplicationModal)
            dialog.exec_()
        else:
            try:
                info = QMessageBox()
                info.setText("正在下载中。。。")
                info.setWindowTitle("Information")
                info.setStandardButtons(QMessageBox.Ok)
                info.button(QMessageBox.Ok).animateClick(3 * 1000)
                info.exec_()
                download(url,path)
            except Exception as e:
                print("error")





if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

 

我们运行一下软件:已经成功了

《Mac配置PyQt5+pyCharm并使用》

三、打包应用

我们编辑程序后,每次运行都要在终端中使用,正常来说,在mac上都是使用app的包直接打开。研究了一下打包软件,最后选择pyinstaller来打包。

pip3 install  pyinstaller

接着我们进行打包,下边是简化打包命令。

mac打包的图标需要icns格式的,可以从这个网址直接下载:https://www.easyicon.net

# 直接打包不带icon
pyinstaller -Fw main.py
# 打包带icon
pyinstaller -Fw  -i icon.icns main.py

完整打包命令:

pyinstaller --windowed --onefile --icon=sat_tool_icon.icns --clean --noconfirm  main.py
pyinstaller --clean --noconfirm --windowed --onefile main.spec
# 如果需要图标,则第一条使用
pyinstaller --windowed --onefile --icon=sat_tool_icon.icns --clean --noconfirm main.py

分开打包可以更改spec文件,比如mac上打包需要分辨率更高的,直接使用pyinstaller打包会比较模式,我们直接在生成的spec文件中增加下放代码:

info_plist={
             'NSHighResolutionCapable':'True',
             }

《Mac配置PyQt5+pyCharm并使用》

好了,到这里就打包结束了,我们看一下打包结果:

《Mac配置PyQt5+pyCharm并使用》

看着最后运行的应用,虽然折腾了一个周末,但是发现入门还是比较简单,成果令人欣喜,最后代码已经上传到github上了:https://github.com/chenlong1314/v_down

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注