2009年12月3号研究了一下如何发布pyqt的程序,整理内容如下:
pyqt是qt图形库对于python编程语言的一个绑定,qt是著名的跨平台图形开发库,专业,易用,以及企业级别支持,文档齐全。python是一个简单易用的解释语言。不过这篇文章是关于如何发布pyqt程序的,那么读者应该都知道这些,我就不多介绍了。
我们用pyqt开发完程序的时候,得到的是一堆python源代码,以及一些资源文件,比如用到的图片,声音什么的。程序在我们开发平台上可以运行,但是我们还需要想办法让客户机也能够用我们的代码。
我们需要做2件事情:一个是把源代码打包成可以放到任何电脑都能够执行的程序,另一个是做一个安装程序,好方便安装到客户机上。
我现在选择py2exe作为打包的工具,nsis作为生成安装程序的工具。
py2exe
nsis
nsis下载后文档中有详细的介绍,安装目录中含有许多的示例。
我写的示例在 这里
稍微解释一下: 比如,我写了一个新的专案,名称叫test_pyqt,新建了一个这样的文件夹。 里面有一个main.py源代码。同时还有一个res的资源目录。 为了能够利用py2exe打包,需要新建一个setup.py的设置文件。
几个难点整理如下: 根据py2exe里面说的,pyqt需要包含sip(我也不知道这是什么东西,估计是C++转python的时候要用到的。。),下面的脚本含有具体的设置。 编译好的文件还需要一些额外的dll文件(主要是针对没有加sp的XP版本运行时出现“程序出错”报错的状况),放在dll文件夹里面,打包的时候要加上(dll文件在上面的示例中)。我没有研究出如何把这些文件加到可执行文件里面的办法,如果你知道的话,就告诉我。
内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
执行:
python setup.py py2exe
以上语句需要把python的目录加到path里面去,或者你可以在python前加上完整的python安装目录. 我是加path的,因为这样使用python更方便。
之后,会生成temp/dist文件夹,里面就是一个main.exe可执行文件了,还有res文件夹。
之后是生成安装文件,新建一个installer.nsi文件,内容如下(因为比较长,放到最后)。
内容比较多。当时我在做的时候,看了很多的文档才知道具体怎么做。为了方便,你还是用我的示例吧。
下面的内容含有多语言,license页面,安装内容页面,安装目录页面,以及反安装页面。
如果你感兴趣的话可以自己研究,我是被nsis细节给累倒了。
这个文件你只需要改下面软件名称的部分,它会自动把dist打包安装到program files里面,生成执行文件链接到桌面以及菜单项中。
对了,主执行文件的入口是main.py这个源代码。
文件写好后,鼠标右键菜单中有一个compile nsis script的选项,点击就可以生成安装文件。
具体的细节可以看我上面示例的压缩文档。我写了一个makefile来方便快速执行操作(别告诉我你不会用make)。 该示例在windows xp,python2.6,nsis2.46,pyqt4.5,py2exe上测试通过。等以后考虑跨平台版本:
#coding:utf-8
;软件名称
!define NAME "test_pyqt"
;主执行文件
!define EXE "dist\main.exe"
;样式
XPstyle on
;输出的安装文件
OutFile "temp/${NAME}_installer.exe"
;默认目录
InstallDir $PROGRAMFILES\${NAME}
; 检查是否已经安装过
InstallDirRegKey HKLM "Software\${NAME}" "Install_Dir"
;需要管理员权限
RequestExecutionLevel admin
;--------------------------------
; 页面
Page license
Page components
Page directory
Page instfiles
UninstPage uninstConfirm
UninstPage instfiles
;--------------------------------
; 安装主目录
Section "main"
SectionIn RO
; Set output path to the installation directory.
SetOutPath $INSTDIR
; 需要安装的程序
File /r "temp\dist"
; Write the installation path into the registry
WriteRegStr HKLM SOFTWARE\${NAME} "Install_Dir" "$INSTDIR"
; Write the uninstall keys for Windows
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "DisplayName" "${NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "UninstallString" '"$INSTDIR\uninstall.exe"'
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "NoRepair" 1
WriteUninstaller "uninstall.exe"
SectionEnd
; 开始菜单
Section "开始菜单"
CreateDirectory "$SMPROGRAMS\${NAME}"
CreateShortCut "$SMPROGRAMS\${NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
SetOutPath $INSTDIR\dist
CreateShortCut "$SMPROGRAMS\${NAME}\${NAME}.lnk" "$INSTDIR\${EXE}" "" "$INSTDIR\${EXE}" 0
SectionEnd
; 桌面快捷方式
Section "桌面快捷方式"
SetOutPath $INSTDIR\dist
CreateShortCut "$DESKTOP\${NAME}.lnk" "$INSTDIR\${EXE}" "" "$INSTDIR\${EXE}" 0
SectionEnd
;--------------------------------
; Uninstaller
Section "Uninstall"
; Remove registry keys
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\"
DeleteRegKey HKLM SOFTWARE\${NAME}
; Remove directories used
Delete "$DESKTOP\${NAME}.lnk"
RMDir /r "$SMPROGRAMS\${NAME}"
RMDir /r "$INSTDIR"
SectionEnd
;--------------------------------
; 语言部分
; First is default
LoadLanguageFile "${NSISDIR}\Contrib\Language files\English.nlf"
LoadLanguageFile "${NSISDIR}\Contrib\Language files\SimpChinese.nlf"
; License data
; Not exactly translated, but it shows what's needed
LicenseLangString myLicenseData ${LANG_ENGLISH} "license.txt"
LicenseLangString myLicenseData ${LANG_SIMPCHINESE} "license.txt"
LicenseData $(myLicenseData)
; Set name using the normal interface (Name command)
; LangString Name ${LANG_ENGLISH} "English"
; LangString Name ${LANG_SIMPCHINESE} "Simplified Chinese"
; Name $(Name)
;--------------------------------
Function .onInit
;Language selection dialog
Push ""
Push ${LANG_ENGLISH}
Push English
Push ${LANG_SIMPCHINESE}
Push "Simplified Chinese"
Push A ; A means auto count languages
; for the auto count to work the first empty push (Push "") must remain
LangDLL::LangDialog "Installer Language" "Please select the language of the installer"
Pop $LANGUAGE
StrCmp $LANGUAGE "cancel" 0 +2
Abort
FunctionEnd
[/sourcecode]
2010/10/29修改: 其实现在pyinstaller用起来更方便, 直接build就可以了. python2.6以后的版本需要下载开发版本使用.