转载,来自:https://caiguanhao.wordpress.com/2013/12/31/pyqt-retina/
前几天买了MBP Retina,发现用PyQt4编出来的Mac app不是Retina,Widget和窗口的左上角的三个按钮都是模糊的,一查发现Qt5开始支持Retina,于是就去装了。
PyQt4贪方便,用了Homebrew安装,于是继续安装PyQt5,发现除了个问题,就是Mac OS X 10.9就把libstdc++改成了libc++,导致PyQt5不能安装,上到Homebrew的Github Issues找答案,有可能需要重新安装大部分软件。
于是还是不能偷懒,去把Qt5和PyQt5的源码下载,自己从源代码build。
第一次Build分别用了Python2.7和Python3.3,都成功,Python3.3可以用,但Python2.7不能用,会出现Symbol not found的错误。
为什么特别要用Python2.7呢?因为PyInstaller目前支持到Python2.7,而另外一个Package软件Pyside又不支持Qt5。所以如果PyQt5不能在Python2.7使用,基本上要Python写的Qt程序不能用Retina。
后来发现PyInstaller需要一个叫SIP的软件,由于学这个时间只有几天,不知道是什么,最后还是把那个也用Python2.7装了,最终可以在Python2.7使用PyQt5,OK。我估计原因是之前的SIP是Homebrew用Python3安装的。
Qt4迁移到Qt5也是一个问题,因为网络上几乎没有任何Qt5的教程,如果现在入手PyQt5,无奈地要看PyQt4的教程,然后安装迁移提示升级。
Qt5安装:
官网上有Mac的安装软件,可以安装到家目录下:~/Qt5.2.0
SIP安装:
cd sip-4.15.3
python2.7 ./configure.py
make
sudo make install
PyQt5安装,–qmake的路径根据Qt5的目录,里面肯定有个叫qmake的程序,–sip和–sip-incdir根据之前SIP安装的输出结果,sudo make install时会列出sip和sip.h这两个文件的路径,分别填入目录和文件路径即可:
cd PyQt-gpl-5.1.1
python2.7 ./configure.py –qmake /Users/caiguanhao/Qt5.2.0/5.2.0/clang_64/bin/qmake –sip-incdir /usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/include/python2.7/ –sip /usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/bin/sip
make
sudo make install
现在应该可以用PyQt5生成app了。但还不是Retina的。
当然还有一步,根据这里,在生成的app文件下找到Info.plist,加入:
1 2 | <key>NSHighResolutionCapable</key> <string>True</string> |
当然这不能通过填写spec文件自动修改,因为PyInstaller生成的Info.plist是固定的,你要更改PyInstaller/build.py大约1500行的位置。
用以下命令直达该目录:
cd $(python2.7 -c "import site; print site.getsitepackages()[0]")/PyInstaller
后加官方现在支持Retina了:
Spec File Options For Mac OS X Apps
If you want to create .app
file, create an instance of BUNDLE
. You can specify the version number and icon file, add or overwrite default settings in Info.plist. For example, when you use PyQt5, set NSHighResolutionCapable to True to let your app also work in retina screen:
1 2 3 4 5 6 7 | exe = EXE(pyz, a.scripts, exclude_binaries=True, name='example', debug=False, strip=None, upx=True, console=False ) bundle = BUNDLE(exe, a.binaries, a.zipfiles, a.datas, info_plist={ 'NSHighResolutionCapable': 'True' }, version='0.0.1', icon='example.icns', name='example.app') |