在Ubuntu 14.04上构建PyQt5的问题

Jos*_*eph 5 python ubuntu qt5 pyqt5

我在Ubuntu 14.04上构建PyQt5时遇到了一些问题.我正在使用一些对Python 2.7具有硬依赖性的代码; 所以,我无法使用Ubuntu存储库中的python3包.对Ubuntu软件包的进一步搜索显示,Python 2 pyqt5有dev和doc软件包.但是,没有什么可以安装编写代码所需的库.

这促使我为PyQt5创建了一个自定义构建.我从这里获得了5.5版本的源代码:https://www.riverbankcomputing.com/software/pyqt/download5我正在使用Ubuntu repos提供的sip(安装kubuntu-desktop需要sip).

我读到很容易有不匹配的sip版本,所以我做了以下检查:

Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sip
>>> print(sip, sip.SIP_VERSION_STR)
(<module 'sip' from '/usr/lib/python2.7/dist-packages/sip.so'>, '4.16.9')
Run Code Online (Sandbox Code Playgroud)

和:

$ sip -V
4.16.9
Run Code Online (Sandbox Code Playgroud)

我也在使用Ubuntu repos提供的Qt5工具.这包括安装qtdeclarative5-*(可能是矫枉过正)和qt5-default.以下是有关qmake的一些信息:

qmake --version
QMake version 3.0
Using Qt version 5.2.1 in /usr/lib/x86_64-linux-gnu
Run Code Online (Sandbox Code Playgroud)

我目前安装了PyQt4,并在安装说明中阅读,只要它们都是针对相同版本的sip进行编译就可以了.

下载后,我解压缩tarball并尝试构建如下:

sudo ln -s  /usr/include/python2.7  /usr/local/include/python2.7
python configure.py --sip-incdir=/usr/include/python2.7/
make
Run Code Online (Sandbox Code Playgroud)

配置输出似乎识别正确的sip版本,我从make得到以下(看似)sip相关的编译错误:

make[1]: Entering directory `~/Downloads/PyQt-gpl-5.5/QtWebKit'
g++ -c -m64 -pipe -fno-exceptions -O2 -Wall -W -D_REENTRANT -fPIC -DSIP_PROTECTED_IS_PUBLIC -Dprotected=public -DQT_NO_DEBUG -DQT_PLUGIN -DQT_WEBKIT_LIB -DQT_NETWORK_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64 -I. -I. -I/usr/include/python2.7 -I/usr/include/qt5 -I/usr/include/qt5/QtWebKit -I/usr/include/qt5/QtNetwork -I/usr/include/qt5/QtGui -I/usr/include/qt5/QtCore -I. -o sipQtWebKitQWebSecurityOrigin.o sipQtWebKitQWebSecurityOrigin.cpp
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp: In function ‘PyObject* meth_QWebSecurityOrigin_addAccessWhitelistEntry(PyObject*, PyObject*)’:
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:384:9: error: ‘SubdomainSetting’ is not a member of ‘QWebSecurityOrigin’
         QWebSecurityOrigin::SubdomainSetting a2;
         ^
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:384:46: error: expected ‘;’ before ‘a2’
         QWebSecurityOrigin::SubdomainSetting a2;
                                              ^
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:387:214: error: ‘a2’ was not declared in this scope
         if (sipParseArgs(&sipParseErr, sipArgs, "BJ1J1E", &sipSelf, sipType_QWebSecurityOrigin, &sipCpp, sipType_QString,&a0, &a0State, sipType_QString,&a1, &a1State, sipType_QWebSecurityOrigin_SubdomainSetting, &a2))
                                                                                                                                                                                                                      ^
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:389:21: error: ‘class QWebSecurityOrigin’ has no member named ‘addAccessWhitelistEntry’
             sipCpp->addAccessWhitelistEntry(*a0,*a1,a2);
                     ^
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp: In function ‘PyObject* meth_QWebSecurityOrigin_removeAccessWhitelistEntry(PyObject*, PyObject*)’:
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:417:9: error: ‘SubdomainSetting’ is not a member of ‘QWebSecurityOrigin’
         QWebSecurityOrigin::SubdomainSetting a2;
         ^
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:417:46: error: expected ‘;’ before ‘a2’
         QWebSecurityOrigin::SubdomainSetting a2;
                                              ^
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:420:214: error: ‘a2’ was not declared in this scope
         if (sipParseArgs(&sipParseErr, sipArgs, "BJ1J1E", &sipSelf, sipType_QWebSecurityOrigin, &sipCpp, sipType_QString,&a0, &a0State, sipType_QString,&a1, &a1State, sipType_QWebSecurityOrigin_SubdomainSetting, &a2))
                                                                                                                                                                                                                      ^
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:422:21: error: ‘class QWebSecurityOrigin’ has no member named ‘removeAccessWhitelistEntry’
             sipCpp->removeAccessWhitelistEntry(*a0,*a1,a2);
                     ^
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp: In function ‘void* init_type_QWebSecurityOrigin(sipSimpleWrapper*, PyObject*, PyObject*, PyObject**, PyObject**, PyObject**)’:
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:477:48: error: no matching function for call to ‘QWebSecurityOrigin::QWebSecurityOrigin(const QUrl&)’
             sipCpp = new QWebSecurityOrigin(*a0);
                                                ^
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:477:48: note: candidates are:
In file included from ~/Downloads/PyQt-gpl-5.5/sip/QtWebKit/qwebsecurityorigin.sip:26:0:
/usr/include/qt5/QtWebKit/qwebsecurityorigin.h:64:5: note: QWebSecurityOrigin::QWebSecurityOrigin(QWebSecurityOriginPrivate*)
     QWebSecurityOrigin(QWebSecurityOriginPrivate* priv);
     ^
/usr/include/qt5/QtWebKit/qwebsecurityorigin.h:64:5: note:   no known conversion for argument 1 from ‘const QUrl’ to ‘QWebSecurityOriginPrivate*’
/usr/include/qt5/QtWebKit/qwebsecurityorigin.h:58:5: note: QWebSecurityOrigin::QWebSecurityOrigin(const QWebSecurityOrigin&)
     QWebSecurityOrigin(const QWebSecurityOrigin& other);
     ^
/usr/include/qt5/QtWebKit/qwebsecurityorigin.h:58:5: note:   no known conversion for argument 1 from ‘const QUrl’ to ‘const QWebSecurityOrigin&’
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp: At global scope:
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:516:48: error: ‘AllowSubdomains’ is not a member of ‘QWebSecurityOrigin’
     {sipName_AllowSubdomains, static_cast<int>(QWebSecurityOrigin::AllowSubdomains), 21},
                                                ^
~/Downloads/PyQt-gpl-5.5/QtWebKit/sipQtWebKitQWebSecurityOrigin.cpp:517:51: error: ‘DisallowSubdomains’ is not a member of ‘QWebSecurityOrigin’
     {sipName_DisallowSubdomains, static_cast<int>(QWebSecurityOrigin::DisallowSubdomains), 21},
                                                   ^
make[1]: *** [sipQtWebKitQWebSecurityOrigin.o] Error 1
make[1]: Leaving directory `~/Downloads/PyQt-gpl-5.5/QtWebKit'
make: *** [sub-QtWebKit-make_first-ordered] Error 2
Run Code Online (Sandbox Code Playgroud)

结果是我可以进行安装并获得一些我期望的功能; 但是,我缺少一些WebKit小部件所需的功能.我希望我提供了足够的信息来描述我被困在哪里.我觉得只是羞于挖掘代码; 但是,我假设答案实际上要简单得多.

提前致谢!

Jos*_*eph 7

所以,

我开始在源代码包中搜索无法编译的文件.在sip目录中有一个sip文件QWebSecurityOrigin,它包含以下内容:

%If (Qt_5_2_0 -)

    enum SubdomainSetting
    {
        AllowSubdomains,
        DisallowSubdomains,
    };

%End
Run Code Online (Sandbox Code Playgroud)

我可以合理地期望将此代码包含在内,因为qmake告诉我以下内容:

qmake --version
QMake version 3.0
Using Qt version 5.2.1 in /usr/lib/x86_64-linux-gnu
Run Code Online (Sandbox Code Playgroud)

接下来我想查看Qt提供的qwebsecurityorigin.h,看看错误是否来自那里.我的安装在这里:/usr/include/qt5/QtWebKit/qwebsecurityorigin.h

#ifndef _WEBSECURITYORIGIN_H_
#define _WEBSECURITYORIGIN_H_

#include <QtCore/qurl.h>
#include <QtCore/qshareddata.h>

#include "qwebkitglobal.h"

namespace WebCore {
    class SecurityOrigin;
    class ChromeClientQt;
}

class QWebSecurityOriginPrivate;
class QWebDatabase;
class QWebFrame;

class QWEBKIT_EXPORT QWebSecurityOrigin {
public:
    static QList<QWebSecurityOrigin> allOrigins();
    static void addLocalScheme(const QString& scheme);
    static void removeLocalScheme(const QString& scheme);
    static QStringList localSchemes();

    ~QWebSecurityOrigin();

    QString scheme() const;
    QString host() const;
    int port() const;

    qint64 databaseUsage() const;
    qint64 databaseQuota() const;

    void setDatabaseQuota(qint64 quota);
    void setApplicationCacheQuota(qint64 quota);

    QList<QWebDatabase> databases() const;

    QWebSecurityOrigin(const QWebSecurityOrigin& other);
    QWebSecurityOrigin &operator=(const QWebSecurityOrigin& other);
private:
    friend class QWebDatabase;
    friend class QWebFrameAdapter;
    friend class WebCore::ChromeClientQt;
    QWebSecurityOrigin(QWebSecurityOriginPrivate* priv);

private:
    QExplicitlySharedDataPointer<QWebSecurityOriginPrivate> d;
};
Run Code Online (Sandbox Code Playgroud)

注意,没有定义枚举.搜索Qt 5.5表明枚举应该在那里:http://doc.qt.io/qt-5/qwebsecurityorigin.html#SubdomainSetting-enum

最后,回想一下,我从大量的Qt库中分别安装了libqt5webkit; 所以,我对包进行了版本检查:

dpkg -s libqt5webkit5
Package: libqt5webkit5
Status: install ok installed
Priority: optional
Section: libs
Installed-Size: 34225
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Multi-Arch: same
Source: qtwebkit-opensource-src
Version: 5.1.1-1ubuntu8
Run Code Online (Sandbox Code Playgroud)

对于dev包,此输出几乎相同.所以这使得它看起来像repos中的Qt5发行版的大部分版本与webkit不同.此外,如果QWebKit在5.1.1上,它将解释为什么枚举失踪,因为sip文件似乎表明它是5.2.0中的一个补充.

所以我的解决方案是使用自动安装程序从Qt网站下载并安装Qt 5.5(使用sudo运行,使用默认值).然后,我通过吹掉构建目录并再次解压缩源来开始使用PyQt5源:

python configure.py --sip-incdir=/usr/include/python2.7/ --qmake=/opt/Qt/5.5/gcc_64/bin/qmake 
make
sudo make install 
Run Code Online (Sandbox Code Playgroud)

许可证不兼容; 但是,使用错误输出快速搜索pyqt5 configure.py脚本可能会让您深入了解如何配置和编译代码.