前言
老规矩,先来个前言。最近用python3和pyqt5写了个程序,考虑到和其他同事要开发环境一致,需要将程序运行环境切换成python2。但直接用python2肯定是跑不通的,因为pyqt5不支持python2……查了下只能对pyqt5源码重新编译。过程也满满都是坑……废话少说,直接上操作。
一、环境搭建
1、下载sip和PyQt5
本机运行环境:Ubuntu18.04、Python2.7
如果说你的系统默认调用的是python3的话,那记得先切回python2.7
另外需要下载sip和PyQt5的源码包,我用的版本为:
sip-4.19.8
PyQt5-5.10.1
上面两个都是官网链接。这里推荐直接去官网下载,照网上其他人说的好像github的编译会出问题,因此我就没尝试。
说明:sip是RiverBank(也就是PyQt的开发商)开发的用于PyQt的Python/C++混合编程解决方案。由于Qt框架的复杂性,PyQt并没有使用Cython、SWIG的混合编程方案,而是自己单独做了一套框架。如果PyQt想正常运行,sip的版本和PyQt5的版本必须对应上,但是他们之间的版本在字面上并没有什么关联性,也就是你根本不知道你这个PyQt5对用的sip版本是什么,这个可是坑了我特别久,可以说在编译过程产生的所有问题都是因为版本不匹配导致的,并且无论是官方还是民间都没有给出两者匹配的版本说明。。
这里也提供下其他版本的下载地址,欢迎尝试:
sip各个版本的下载链接
PyQt5各个版本的下载链接
我前前后后试了N个版本,最后只有两个可行:
PyQt版本 |
sip版本 |
5.10.1 |
4.19.8 |
5.11.3 |
4.19.14 |
2、移除本机自带sip
先查看有没有sip,防止后续安装失败:
ls /usr/lib/python2.7/dist-packages/sip*
如果有的话,直接sudo rm删除:
sudo rm -rf /usr/lib/python2.7/dist-packages/sip*
二、解压编译
1、sip解压编译
进入sip下载好的路径,打开终端,执行下面指令,一般sip的编译不会出现啥报错。
tar -xzvf sip-4.19.8.tar.gz
cd sip-4.19.8
python configure.py
make
sudo make install
查看是否安装上了,两者输出版本号即可
sip -V #终端查看sip版本
python #进入python命令行查看
import sip
print(sip.SIP_VERSION_STR)
2、PyQt5解压编译
同理,进入下载目录打开终端执行:
tar -xzvf PyQt5_gpl-5.10.1.tar.gz
cd PyQt5_gpl-5.10.1
python configure.py --sip-incdir=/usr/include/python2.7
# 根据提示输入yes回车,在这里如果版本不匹配会提示出错
make -j4 #这里会报错,解决方法在下面
sudo make install
make -j4编译过程出现报错error: ‘waitForEvents’ is not a member of ‘QTest’
这个函数自从5.10 / 5.11版本之后,去掉了。所以这里找不到,简单的办法就是按照提示找到调用该函数的地方,将其注释掉。
这个函数不重要,只有一个地方调用了,所以直接注释掉就OK了。
如果出现其他错误,不用怀疑,就是版本不匹配导致的!!!
测试
进入python命令行导入PyQt5库
python
import PyQt5 #没报错,ok
将原程序更换成python2运行,将第一行的
#!/usr/bin/env python3换成python2
报错1:ImportError: No module named sip
这种是版本不匹配,编译的时候没报错通过了,但是运行就不行了。PyQt5调用不到sip库导致的。
报错2:Segmentation fault (core dumped)
还是版本不匹配。
报错3:出现TypeError: super() takes at least 1 argument (0 given)
原因是super().init()函数在python3中支持,是正确的,但是放到python2中会出现问题;
如果在python2想要继承父类的构造方法,则需要给super参数中传入参数:super(base_model,self).init();
原代码:
class MyWin(QWidget):
def __init__(self):
super(self).__init__()
很简单,给super里传入类名即可:
class MyWin(QWidget):
def __init__(self):
super(MyWin,self).__init__()
成功
本文参考链接:
CSDN博主@雪峰流云
CSDN博主@爱发呆de白菜头
知乎:同时安装PyQt4和PyQt5之sip版本区分
欢迎补充,有错误请指正,有用请点个赞吧~