最近,我参与了有关为Qt和QtQuick Ubuntu应用程序创建Quickly模板的对话。这样做的目的是像现在使用GTK(基于Ubuntu应用程序Quickly模板)的GTK一样,使从概念到软件包的Qt应用程序开发变得容易。
意图仍然是使用Python作为基础编程语言,想到的第一个问题是:我们应该使用PyQt还是PySide绑定哪个Python绑定?
我想从两种技术的经验丰富的人那里了解到每种技术的优缺点,每种技术的维护程度,将Qt API映射到绑定的方式等等。
谢谢!
最近,我参与了有关为Qt和QtQuick Ubuntu应用程序创建Quickly模板的对话。这样做的目的是像现在使用GTK(基于Ubuntu应用程序Quickly模板)的GTK一样,使从概念到软件包的Qt应用程序开发变得容易。
意图仍然是使用Python作为基础编程语言,想到的第一个问题是:我们应该使用PyQt还是PySide绑定哪个Python绑定?
我想从两种技术的经验丰富的人那里了解到每种技术的优缺点,每种技术的维护程度,将Qt API映射到绑定的方式等等。
谢谢!
Answers:
PyQt4和PySide都具有与Qt API非常相似的映射。但是,存在一些差异,以下是我对此的看法:
它们都维护得很好。目前,PySide产生了更多的常规发行版:我认为它与Qt的联系比PyQt4更紧密,并且作为一个较新的项目,现在社区更加活跃。但是,那只是我的印象,可能是错误的。
PyQt4可以选择提供商业支持(我不知道PySide是否适用)。
PyQt4是根据商业许可或GPL发布的;PySide是根据LGPL发行的。对于商业应用,这是一个很大的差异。
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.QString
s并再次返回。在API版本2(和PySide)中,您始终使用python字符串。如果您想同时使用两者,请参阅下文,了解在PyQt4和PySide之间切换的简单方法。
我编写的大多数代码在PyQt4和PySide中似乎同样有效。从历史上看,我一直将PyQt4用于python GUI,但是我现在写的大多数新东西都使用PySide(主要是由于许可更加灵活)。我当然建议您同时尝试一下,看看如何找到它们。如果您使用QtVariant.py(如下),则在它们之间进行切换很简单,并且当您做出决定时,只会有一个文件需要更新。
PyQt4和PySide的文档都是从Qt主文档自动生成的。在我看来,PySide文档可以更好地表示您实际使用的内容,但实际上,我还是倾向于只使用Qt文档(将C ++文档转换为python相当容易)。
如果您使用的是外部库,则某些库还不能与PySide一起使用。老实说,您不需要与PySide一起工作,但是几年前,我编写了一些代码,这些代码使用Twisted(与Qt反应器一起使用)和matplotlib,迫使我不得不使用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]
return QtUiTools.QUiLoader().load(uifile)
,无需任何QFile样板即可获取文件路径。