用 PyInstaller 打包基于 PyQt 的程序遇到的坑

MarianoK92 7年前發布 | 19K 次閱讀 PyQt Python開發

之前寫了個腳本自己平常工作用,最近因為需要把腳本給其他同事用,為了避免它們還需要配置環境,于是用 PyQt 寫了個界面,然后用 PyInstaller 打包成 exe 。打包過程中遇到了一些坑,紀錄一下。

PyQt

之前寫過一個 蝦米歌單導出 小腳本,exe 版本是用的 Python 自帶的 Tkinter 寫的,所以這次嘗試用 PyQt。寫的時候遇到了任務欄閃爍和打包后程序界面圖標不顯示的問題。

  • 任務欄閃爍提示

    后臺運行程序的時候,如果使用 QFileDialog ,程序彈出保存對話框的時候會在任務欄閃爍提示。但不是每個 Widget 都會有這個功能,但是這時候可以通過 QtWidget 的 activateWindow() 和 QApplication.alert() 來實現,但這兩者使用的時候會有點區別。

    activateWindow() 是實例方法,只要程序窗口切換到前臺被激活了就不會再閃爍。而 QApplication.alert(QWidget, msecs: int = 0) 是靜態方法, msecs 值為 0 的時候,和 activateWindow() 的效果一致,但是需要在閃爍停了之后激活程序才會任務欄窗口顏色才會恢復正常,否則還是黃色,直到閃爍停了之后再激活一次程序。 msecs 不為 0 的時候,超過這個時間后,任務欄窗口就會自動恢復正常。 所以 activateWindow() 是比較好的選擇,除非不要求一直在任務欄提示。

  • 資源文件在打包時的處理

    把代碼用 PyInstaller 打包到一個文件的時候,會出現圖標或圖片都不顯示的情況。這種時候就需要用 Qt’s resource system 來對其進行打包。

    首先新建一個 .qrc 文件,內容格式如下:

    <RCC>
      <qresource prefix="/" >
        <file>img/image1.png</file>
        <file>img/image2.png</file>
        <file>img/image3.png</file>
      </qresource>
    </RCC>

    然后去文件目錄下執行 pyrcc5 -o images_qr.py images.qrc 命令,最后在代碼中 import image_qr.py,并且修改下圖片路徑,一定要在路徑前面加上冒號。

    import image_qr.py
    # your code
    self.setWindowIcon(QtGui.QIcon(':/img/image1.png'))

    ?

PyInstaller

之前用 cx_freeze 打過包,但感覺不理想,搜索了下發現 PyInstaller 用得比較多,就使用了這個,第一次用的時候沒遇到問題, 但是因為 Python 是裝的 64 位的,所以打包之后的程序無法在 32 位的機器上使用 。這就意味著我必須要在 Python 32 位的環境下打包,但重新配置了下環境之后,遇到了 ImportError 和無法鏈接到動態庫的問題。

  • ImportError: DLL load failed

    用 PyInstaller 給程序打包的時候遇到了 pyi_rth_qt5plugins returned -1 的 Fatal Error 提醒。這個錯誤信息幾乎是毫無用處的,修改 .spec 文件,打開 debug 模式以及顯示 console 后,在 running pyi_rth_qt5plugins.py 的時候發生了 ImportError: DLL load failed 找不到指定的模塊 錯誤。

    回頭想起了在編譯的時候看到了很多 WARNNING 消息,回過頭查看,發現了很多 lib not found 的問題。但是仔細檢查了 Python 庫之后,這些 DLL 明明在 C:\Python35-32\Lib\site-packages\PyQt5\Qt\bin 目錄下,最后的搜索得到的解決辦法是把這個目錄添加到環境變量里。

    問題得到了解決,猜測原因是因為之前使用 pip 安裝 PyQt 的時候, pypi.python.org 總是連接不順暢,最后去下了個 .whl 文件直接安裝,導致沒有對應環境變量打包的時候找不到 DLL。

    # 環境: Python == 3.5.2 ,PyInstaller == 3.1.1
    
    10951 WARNING: lib not found: Qt5Svg.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\imageformats\qsvg.dll
    11206 WARNING: lib not found: Qt5Gui.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\imageformats\qsvg.dll
    11437 WARNING: lib not found: Qt5Core.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\imageformats\qsvg.dll
    11763 WARNING: lib not found: Qt5Gui.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\imageformats\qtga.dll
    12017 WARNING: lib not found: Qt5Core.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\imageformats\qtga.dll
    12224 WARNING: lib not found: Qt5Gui.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\platforms\qminimal.dll
    12418 WARNING: lib not found: Qt5Core.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\platforms\qminimal.dll
    12625 WARNING: lib not found: Qt5Gui.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\platforms\qwindows.dll
    12833 WARNING: lib not found: Qt5Core.dll dependency of C:\python35-32\lib\site-packages\PyQt5\Qt\plugins\platforms\qwindows.dll
  • api-ms-win-crt-runtime 錯誤

    PyInstaller 打包之后的程序運行的時候發生 api-ms-win-crt-runtime 動態庫之類的錯誤,似乎只有在 Python 3.5 下打包才會遇到。因為 Universal CRT (KB2999226)缺失,可以通過安裝此更新來解決問題。或者直接下載 Visual C++ Redistributable ( x86 , x64 )。

    這次的幾個坑讓我更堅定這類工具最好不要用最新版本,一不見得更穩定,二是遇到問題資料也比較少,在這類不必要的麻煩上花太多時間不值得,除非新版本能有很大的收益。

 

來自:http://www.jianshu.com/p/c1e75244b6f3

 

 本文由用戶 MarianoK92 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!