首页 > 解决方案 > 使用 PyInstaller 减小 Python 应用程序的大小

问题描述

我正在使用 PyQt5 和 PyQtChart (QtCharts) 开发实时绘图应用程序。出于演示目的,这是我的超级简单应用程序:

import sys
import numpy
import PyQt5.QtWidgets
import PyQt5.QtChart
import PyQt5.Qt
import PyQt5.QtCore
import PyQt5.QtGui

class Plot(PyQt5.QtWidgets.QWidget):
    def __init__(self):
        PyQt5.QtWidgets.QWidget.__init__(self)

        self.time = 0

        self.plot = PyQt5.QtChart.QChart()
        self.plot.setTitle("Plot")

        self.chartView = PyQt5.QtChart.QChartView(self.plot)

        self.series = PyQt5.QtChart.QLineSeries()
        self.plot.addSeries(self.series)
        self.plot.createDefaultAxes()

        self.axisX = self.plot.axisX()
        self.axisX.setRange(0, 100)
        self.axisX.setTitleText("Two")

        self.axisY = self.plot.axisY()
        self.axisY.setRange(0, 10)
        self.axisY.setTitleText("One")

        vBox = PyQt5.QtWidgets.QVBoxLayout()
        vBox.addWidget(self.chartView)
        self.setLayout(vBox)

    def add_point(self, point):
        self.time += 1
        self.series.append(self.time, point)

        if self.time > 100:
            self.axisX.setRange(self.time - 100, self.time)

class MainWindow(PyQt5.QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.plot = Plot()
        self.setCentralWidget(self.plot)

        self.pollTimer = PyQt5.QtCore.QTimer()
        self.pollTimer.setInterval(100)
        self.pollTimer.timeout.connect(self.update_plot)
        self.pollTimer.start()

    def update_plot(self):
        self.plot.add_point(numpy.random.randint(0, 10));

if __name__ == '__main__':
    app = PyQt5.QtWidgets.QApplication(sys.argv)

    mainWindow = MainWindow()

    mainWindow.resize(640, 480)
    mainWindow.show()

    sys.exit(app.exec_())

然后我在 PyInstaller 的帮助下将应用程序捆绑到一个可执行文件中。这是我正在使用的 .spec 文件:

# -*- mode: python -*-

block_cipher = None

a = Analysis(['source\\PyQt5-Plotter.py'],
             pathex=[],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)

pyz = PYZ(a.pure,
          a.zipped_data,
          cipher=block_cipher)

exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='PyQt5-Plotter',
          debug=False,
          strip=False,
          upx=True,
          console=False)

coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='PyQt5-Plotter')

完成后,我的应用程序大小为 207 MB,分布在 1,408 个文件中!对于一个 60 行的程序来说似乎有点粗糙 :) 简而言之,一个简单的 PyQt5 应用程序(没有 QtCharts)在 60 个文件中可能是 40 MB。

我不知道为什么 QtCharts 应用程序会捆绑大量文件和大量 dll,例如 Qt5WebEngineCore.dll,它本身就超过 50 MB。事实上,如果我从应用程序目录中删除它,程序仍然可以正常运行。

所以我的问题是 - 我将如何将我的应用程序缩小到所需的内容?我知道 PyInstaller 排除项,但是对数百个文件进行排序并一次排除一个文件会很糟糕。

建议?谢谢。

标签: pythonexecutablepyinstallerminify

解决方案


推荐阅读