简体中文 English

PySide 与 PyQt 的差异

API 差异

不同的 import 名字 (PySide 而不是 PyQt4)

PySide 使用不同的库名而不是用PyQt。不要输入:

  1. from PyQt4.QtCore import *


  1. import PyQt4.QtCore

而是必须像下面这样:

  1. from PySide.QtCore import *


  1. import PySide.QtCore

.

PySide 只支持 PyQt’s “API 2” (PSEP 101)

PyQt 提供了 两套不同的 APIs [riverbankcomputing.co.uk] , 第一套提供了 QStrings, QVariants, 等作为Python类型。新的 API 2 提供了Qt类和python原生数据类型之间的自动转换,这样本质上也更Pythonic。PyQt 在 Python2.x 系列中默认是 API 1,而在 Python 3 中默认是 API 2。

PySide 只支持PyQt 的 API 2(详见 PSEP 101 [pyside.org]) 。因而Qt的类比如 QStrings, QStringLists, 和 QVariants 在PySide不可用。作为替代,你应该使用原生的Python的数据类型。

如果你要从 PyQt 移植代码,你可能愿意先修改 PyQt 的代码使之使用 API 2(通过在导入 PyQt4 之前调用 sip.setapi(class,ver) 来实现),只有在修改的代码工作以后,修改导入部分来使用 PySide。

NB: 由于API的改变,QFileDialog.getOpenFileName 在PySide中返回一个元组。在移植PyQt代码时,这经常产生争论。比如: bug 343 [bugs.openbossa.org].

新式(New-style)信号与槽有稍微不同的语法 (PSEP 100)

不幸的是, 对于新式的信号和槽的类PyQt使用了一个和实现相关的命名规则:

  1. # 定义一个叫做 'trigger' 的没有参数的新的信号
  2. trigger = QtCore.pyqtSignal()

如同在 PSEP 100 [pyside.org] 所描述的,使用 QtCore.Signal()QtCore.Slot() 来代替。

如果你想修改你的 PyQt 代码使之使用 PySide 的命名规则,可以这样简单来实现:

  1. QtCore.Signal = QtCore.pyqtSignal
  2. QtCore.Slot = QtCore.pyqtSlot

.

使用稍有不同的语法完成Qt属性的声明 (PSEP 103)

伴随上面信号与槽语法的修改,声明 Qt 的属性是通过 QtCore. Property 而不是 QtCore.pyqtProperty (见 PSEP 103 [pyside.org])来完成的。

工具名称的差异

PySide 为脚本工具取了不同的名字:

  • pyuic4 -> pyside-uic
  • pyrcc4 -> pyside-rcc4
  • pylupdate4 -> pyside-lupdate

功能性差异

不为Qt 4.5之前废弃(deprecated)的函数生成绑定代码

在PySide,不为在 Qt 4.5之前已经废弃的函数生成绑定代码。

如果一个函数没有在 PySide 中出现,查阅 Qt 在线参考文档 [doc.qt.nokia.com] 来确认该函数是否已经被废弃且用什么来替代。

bug例子: bug 359 [bugs.openbossa.org]

举例来说,这会影响到 QColor.dark()QColor.light() 函数,作为替代 QColor.darker()QColor.lighter() 应当被使用。

sender() 成员在 partial 或 lambda 函数内返回 None

如果一个lambda函数作为一个槽,sender() 不能用来获取发送信号的对象。这在PyQt中是工作的,但是他们的实现在特定情况下行为不太正常。详见 bug 344 [bugs.openbossa.org]

当继承一个类时,父类的构造函数总是需要被调用

在一些情况下 PyQt 允许这样的代码:

  1. class Window(QtGui.QWidget):
  2.     def __init__(self, parent=None):
  3.         super(QtGui.QWidget, self).__init__(parent)
  4.         [...]

在这种情况下,直接父类的构造函数未被调用。PySide 希望你做正确的事情:

  1. class Window(QtGui.QWidget):
  2.     def __init__(self, parent=None):
  3.         super(Window, self).__init__(parent)
  4.         [...]

旧式风格的信号需要使用圆括号

PyQt allows use o short-circuit signals without parentheses such as:

  1. self.emit(SIGNAL('text_changed_cb'), text)

Due this is a old and deprecated feature, and the effort to fix this is not worth, we decided to not implement that, then in PySide code you need to use something like that:

  1. self.emit(SIGNAL('text_changed_cb(QString)'), text)

You can check the complete discussion on bug #314 [bugs.pyside.org]

Categories: