我应该为新的Qt项目使用PyQt还是PySide?


59

最近,我参与了有关为Qt和QtQuick Ubuntu应用程序创建Quickly模板的对话。这样做的目的是像现在使用GTK(基于Ubuntu应用程序Quickly模板)的GTK一样,使从概念到软件包的Qt应用程序开发变得容易。

意图仍然是使用Python作为基础编程语言,想到的第一个问题是:我们应该使用PyQt还是PySide绑定哪个Python绑定?

我想从两种技术的经验丰富的人那里了解到每种技术的优缺点,每种技术的维护程度,将Qt API映射到绑定的方式等等。

谢谢!


那么python-qt4在main中,而python-pyside在Universe中。我想您也应该向Kubuntu的人问这个问题。
Jeremy Bicha

最好将这个问题放在stackoverflow.com或developers.stackexchange.com上。
DrAl 2012年

谢谢@DrAl,是的,我也很想知道,但这是专门为Ubuntu创建一个Quickly模板,这就是为什么我决定使用AskUbuntu。
戴维·普拉内拉

Answers:


63

PyQt4和PySide都具有与Qt API非常相似的映射。但是,存在一些差异,以下是我对此的看法:

保养

它们都维护得很好。目前,PySide产生了更多的常规发行版:我认为它与Qt的联系比PyQt4更紧密,并且作为一个较新的项目,现在社区更加活跃。但是,那只是我的印象,可能是错误的。

PyQt4可以选择提供商业支持(我不知道PySide是否适用)。

执照

PyQt4是根据商业许可或GPL发布的;PySide是根据LGPL发行的。对于商业应用,这是一个很大的差异。

API和Python版本

PyQt4支持两种不同的API。API版本1是python 2.x应用程序的默认值,API版本2是python 3.x应用程序的默认值。

PySide仅支持一个API,大致相当于PyQt4的API版本2。与PyQt4的API版本1相比,API版本2(或PySide API)易于使用。在API版本1中,您可以使用许多强制转换python的代码字符串返回QtCore.QStrings并再次返回。在API版本2(和PySide)中,您始终使用python字符串。如果您想同时使用两者,请参阅下文,了解在PyQt4和PySide之间切换的简单方法。

我编写的大多数代码在PyQt4和PySide中似乎同样有效。从历史上看,我一直将PyQt4用于python GUI,但是我现在写的大多数新东西都使用PySide(主要是由于许可更加灵活)。我当然建议您同时尝试一下,看看如何找到它们。如果您使用QtVariant.py(如下),则在它们之间进行切换很简单,并且当您做出决定时,只会有一个文件需要更新。

文献资料

PyQt4PySide的文档都是从Qt文档自动生成的。在我看来,PySide文档可以更好地表示您实际使用的内容,但实际上,我还是倾向于只使用Qt文档(将C ++文档转换为python相当容易)。

外部图书馆

如果您使用的是外部库,则某些库还不能与PySide一起使用。老实说,您不需要与PySide一起工作,但是几年前,我编写了一些代码,这些代码使用Twisted(与Qt反应器一起使用)和matplotlib,迫使我不得不使用PyQt4而不是PySide 。我认为这些库很可能已经更新到现在都支持,但是我还没有检查。

使代码与PyQt4或PySide一起使用

假设您使用的是python 2.x,则可以通过创建QtVariant.py并使用以下命令,轻松地使代码与PySide PyQt4 兼容:

from QtVariant import QtGui, QtCore

管他呢。我使用的QtVariant.py如下所示:

import sys
import os

default_variant = 'PySide'

env_api = os.environ.get('QT_API', 'pyqt')
if '--pyside' in sys.argv:
    variant = 'PySide'
elif '--pyqt4' in sys.argv:
    variant = 'PyQt4'
elif env_api == 'pyside':
    variant = 'PySide'
elif env_api == 'pyqt':
    variant = 'PyQt4'
else:
    variant = default_variant

if variant == 'PySide':
    from PySide import QtGui, QtCore
    # This will be passed on to new versions of matplotlib
    os.environ['QT_API'] = 'pyside'
    def QtLoadUI(uifile):
        from PySide import QtUiTools
        loader = QtUiTools.QUiLoader()
        uif = QtCore.QFile(uifile)
        uif.open(QtCore.QFile.ReadOnly)
        result = loader.load(uif)
        uif.close()
        return result
elif variant == 'PyQt4':
    import sip
    api2_classes = [
            'QData', 'QDateTime', 'QString', 'QTextStream',
            'QTime', 'QUrl', 'QVariant',
            ]
    for cl in api2_classes:
        sip.setapi(cl, 2)
    from PyQt4 import QtGui, QtCore
    QtCore.Signal = QtCore.pyqtSignal
    QtCore.QString = str
    os.environ['QT_API'] = 'pyqt'
    def QtLoadUI(uifile):
        from PyQt4 import uic
        return uic.loadUi(uifile)
else:
    raise ImportError("Python Variant not specified")

__all__ = [QtGui, QtCore, QtLoadUI, variant]

2
由于PySide很多时候都接受高级Python对象,因此您的UI加载器功能可以简化为return QtUiTools.QUiLoader().load(uifile),无需任何QFile样板即可获取文件路径。
克里斯·比灵顿
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.