对于新的 Qt 项目,我应该使用 PyQt 还是 PySide?

Dav*_*lla 60 python qt pyqt application-development pyside

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

目的仍然是使用 Python 作为基础编程语言,首先想到的问题是:我们应该使用PyQt还是PySide哪些 Python 绑定?

我想听听熟悉这两种技术的人的意见,每种技术的优缺点是什么,每种技术的维护情况如何,Qt API 与绑定的映射情况如何,等等。

谢谢!

DrA*_*rAl 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 API版本2(或PySide API)是很多更好的工作比PyQt4中的API版本1.在API版本1,你有很多的代码,强制转换蟒蛇字符串到QtCore.QStrings 并再次返回。在 API 版本 2(和 PySide)中,您只需在整个过程中使用 python 字符串。如果您想同时使用 PyQt4 和 PySide,请参阅下文了解在 PyQt4 和 PySide 之间切换的简单方法。

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

文档

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

外部图书馆

如果您使用的是外部库,有些库还不能与 PySide 一起使用。老实说,你需要使用 PySide 的并不多,但几年前我写了一些使用扭曲(使用 Qt 反应器)和 matplotlib 的代码,这迫使我放弃使用 PyQt4 而不是 PySide . 我认为这些库现在很可能已经更新以支持两者,但我还没有检查。

使代码与 PyQt4 或 PySide 一起工作

假设你正在使用python 2.x中,你可以很容易使你的代码既PySide兼容PyQt4的通过使QtVariant.py和使用:

from QtVariant import QtGui, QtCore
Run Code Online (Sandbox Code Playgroud)

管他呢。我使用的 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]
Run Code Online (Sandbox Code Playgroud)

  • 由于 PySide 很多时候都接受高级 Python 对象,因此您的 UI 加载器函数可以简化为类似 `return QtUiTools.QUiLoader().load(uifile)` 之类的东西,采用没有任何 QFile 样板的文件路径。 (2认同)