前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从零开始用 PyQt5 写一个 scihub 下载器(二)

从零开始用 PyQt5 写一个 scihub 下载器(二)

作者头像
生信菜鸟团
发布2020-11-03 15:44:38
8970
发布2020-11-03 15:44:38
举报
文章被收录于专栏:生信菜鸟团生信菜鸟团

上一次的教程中,我们已经设计了程序界面,并生成了界面的 .py 脚本。在今天的教程中,我们将介绍如何使用这种界面与逻辑分离的 GUI 程序框架,构建主函数,并最终打包程序为可执行文件。

3. 构建主程序

3.1 界面与逻辑分离的 GUI 程序框架

这里我们采用单继承的界面封装方法,编写主程序 scihub_gui.py 框架,代码如下:

代码语言:javascript
复制
## 单继承方法,能更好地进行界面与逻辑的分离import sysfrom PyQt5.QtWidgets import QApplication, QMainWindowfrom PyQt5.Qt import QStandardPathsfrom scihub_ui import Ui_MainWindowclass CustomUI(QMainWindow):    def __init__(self, parent=None):        super().__init__(parent) # 调用父类构造函数,self 就是一个 QMainWindow 对象        self.ui = Ui_MainWindow() # 创建UI 对象        self.ui.setupUi(self) # 构造UIif __name__ == '__main__':    app = QApplication(sys.argv) # 创建app,用 QApplication 类    cutomUI = CustomUI()    cutomUI.show()    sys.exit(app.exec_())

3.2 实现文献下载功能

本来自己写了个简单的脚本,但前两天在 GitHub 上看到了功能更完善的脚本,所以这里不妨做个调包侠。脚本地址:https://github.com/zaytoun/scihub.py

这个脚本可实现根据 DOI | PMID | URL 下载文献 PDF,使用方法也非常简单:

代码语言:javascript
复制
from scihub import SciHubsh = SciHub()result = sh.download('http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=1648853', path='paper.pdf')

我们将该 Scihub.py 脚本下载下来,放在 scihub_gui.py 的同一目录下,方便调用。

下载文献后,可用 PyPDF2 包提取 PDF 信息,以根据文献标题重命名 PDF 文件:

代码语言:javascript
复制
from PyPDF2 import PdfFileReaderwith open('paper.pdf', 'rb') as f:    pdf = PdfFileReader(f)    info = pdf.getDocumentInfo()    title = info.title

3.3 PyQt5 的事件处理机制

PyQt5 有一个独一无二的信号和槽机制来处理事件。信号和槽用于对象之间的通信。当指定事件发生,一个事件信号会被发射。槽可以被任何 Python 脚本调用。当和槽连接的信号被发射时,槽会被调用。

在 Qt 中,每一个 QObject 对象和 PyQt 中所有继承自 QWidget 的控件(这些都是 QObject 的子对象)都支持信号与槽机制。当信号发射时,连接的槽函数将会自动执行。在 PyQt 5 中信号与槽通过 控件名.信号.connect(槽函数)方法连接。

在我们这个小程序中共包含了两类信号:

1.识别黏贴板的变化2.识别按钮动作

所以下一步我们为 scihub_gui.py 脚本加上亿点点细节,用 QApplication.clipboard() 读取黏贴板信息并重定向输出流(展示在文本区域内),绑定按钮事件(获取参数&触发请求),最后用 QMessageBox 弹出信息框。最终 scihub_gui.py 的代码如下:

代码语言:javascript
复制
import sysfrom PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBoxfrom PyQt5.Qt import QStandardPathsfrom scihub_ui import Ui_MainWindowfrom scihub import SciHubfrom PyPDF2 import PdfFileReaderimport osclass CustomUI(QMainWindow):    def __init__(self, parent=None):        super().__init__(parent)        self.ui = Ui_MainWindow()        self.ui.setupUi(self)        self.cb = QApplication.clipboard()        self.cb.dataChanged.connect(self.monitor_clipboard)        self.ui.textEdit.setText(self.cb.text())        self.ui.pushButton.clicked.connect(self.buttClicked)    def monitor_clipboard(self):        if self.cb.text():            self.ui.textEdit.setText(self.cb.text())    def buttClicked(self):        try:            curPath = QStandardPaths.writableLocation(QStandardPaths.DocumentsLocation) # 默认保存在 ~/Documents            pdf_name = "/paper.pdf" # 默认文件名为 paper.pdf            test = SciHub()            textEditber = self.ui.textEdit.toPlainText()            test.download(textEditber, path= curPath + pdf_name)            with open(curPath + pdf_name, 'rb') as f:                pdf = PdfFileReader(f)                info = pdf.getDocumentInfo()                title = info.title                if title != None and title != "":                    file_name = title.replace(' ',"_")                    file_name = file_name + ".pdf"                    os.rename(curPath + pdf_name, curPath + "/" + file_name)                else:                    file_name = "paper.pdf"        except:            QMessageBox.information(self, '', '下载失败')        else:            QMessageBox.information(self, '', file_name + '下载完成')if __name__ == '__main__':    app = QApplication(sys.argv)    cutomUI = CustomUI()    cutomUI.show()    sys.exit(app.exec_())

•对于一些功能较复杂的程序我们可以把这些进行逻辑操作的函数放到一个新的 .py 文件中,这样可以方便后期维护代码。但在这里因为程序比较简单,所以就直接放在主程序中了。•踩过的坑:在 Qt 中, 当我们需要不调用 QFileDialog 保存文件时,得用 QStandardPaths 指定路径,否则打包出来的软件没法保存。

完成上面的步骤,直接运行程序就可以看到界面啦,复制 DOI 或 PMID,点击 Download即可下载文献了~

4. 打包程序为 Mac App

这里我们用 pyinstaller 来生成可执行程序,安装 pyinstaller

代码语言:javascript
复制
pip install pyinstaller

准备一个软件图标 icon:

可用网站转换 png 至 ico 格式:https://www.easyicon.net/covert/

打包:

代码语言:javascript
复制
pyinstaller --windowed --onefile --clean --noconfirm scihub_gui.py -p scihub.py -i scihub.icns

dist 目录下即可看到打包好的程序:

要是你也装了 Anaconda,你会发现这么简单的小程序体积居然有 100M+,这是因为 Anaconda 里内置了很多库,打包的时候打包了很多不必要的模块进去。所有为了缩小 App 的体积,我们最好在一个新的虚拟环境中进行打包。

创建环境:

代码语言:javascript
复制
conda create -n scihubgui python=3.7

激活环境:

代码语言:javascript
复制
conda activate scihubgui

安装依赖:

代码语言:javascript
复制
pip install -r requirements.txt

requirements.txt

代码语言:javascript
复制
altgraph==0.17beautifulsoup4==4.9.3certifi==2020.6.20chardet==3.0.4idna==2.10macholib==1.14powerline-status==2.7pyinstaller==4.0pyinstaller-hooks-contrib==2020.9PyPDF2==1.26.0PyQt5==5.15.1PyQt5-sip==12.8.1PySocks==1.7.1requests==2.24.0retrying==1.3.3six==1.15.0soupsieve==2.0.1urllib3==1.25.11

打包程序:

代码语言:javascript
复制
pyinstaller --windowed --onefile --clean --noconfirm scihub_gui.py -p scihub.py -i scihub.icns

现在可以看到程序的大小缩小了一半以上(但感觉还是太大了,需要再研究下)。

我已将所有代码上传至 GitHub:https://github.com/zwbao/scihub_gui

教程推荐

1.Qt Documentation:https://doc.qt.io/2.Qt for Python:https://doc.qt.io/qtforpython/#project3.PyQt5 中文教程:https://github.com/maicss/PyQt5-Chinese-tutorial4.《Python Qt GUI与数据可视化编程》

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信菜鸟团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3. 构建主程序
    • 3.1 界面与逻辑分离的 GUI 程序框架
      • 3.2 实现文献下载功能
        • 3.3 PyQt5 的事件处理机制
        • 4. 打包程序为 Mac App
        • 教程推荐
        相关产品与服务
        云开发 CloudBase
        云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档