Differences Between PySide and PyQt/zh: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[Category:LanguageBindings::PySide]]
{{Cleanup | reason=Auto-imported from ExpressionEngine.}}
[[Category:SimplifiedChinese::LanguageBindings::PySide]]
<big>'''Attention: a port of PySide to Qt 5.x started in 2014, the progress and more details about this project can be found under [[PySide2 | PySide 2]]'''</big>
'''简体中文''' [[Differences Between PySide and PyQt|English]]
[[Category:PySide]]
[toc align_right="yes" depth="3"]
{{LangSwitch}}


= PySide 与 PyQt 的差异 =
= PySide 与 PyQt 的差异 =
Line 33: Line 33:
=== PySide 只支持 PyQt's "API 2" (PSEP 101) ===
=== PySide 只支持 PyQt's "API 2" (PSEP 101) ===


PyQt 提供了 "两套不同的 APIs":http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html#selecting-incompatible-apis , 第一套提供了 <code>QStrings</code>, <code>QVariants</code>, 等作为Python类型。新的 API 2 提供了Qt类和python原生数据类型之间的自动转换,这样本质上也更Pythonic。PyQt 在 Python2.x 系列中默认是 API 1,而在 Python 3 中默认是 API 2。
PyQt 提供了 [http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html#selecting-incompatible-apis 两套不同的 APIs] , 第一套提供了 <code>QStrings</code>, <code>QVariants</code>, 等作为Python类型。新的 API 2 提供了Qt类和python原生数据类型之间的自动转换,这样本质上也更Pythonic。PyQt 在 Python2.x 系列中默认是 API 1,而在 Python 3 中默认是 API 2。


PySide 只支持PyQt 的 API 2(详见 "PSEP 101":http://www.pyside.org/docs/pseps/psep-0101.html) 。因而Qt的类比如 <code>QStrings</code>, <code>QStringLists</code>, 和 <code>QVariants</code> 在PySide不可用。作为替代,你应该使用原生的Python的数据类型。
PySide 只支持PyQt 的 API 2(详见 [http://www.pyside.org/docs/pseps/psep-0101.html PSEP 101]) 。因而Qt的类比如 <code>QStrings</code>, <code>QStringLists</code>, 和 <code>QVariants</code> 在PySide不可用。作为替代,你应该使用原生的Python的数据类型。


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


'''NB:''' 由于API的改变,<code>QFileDialog.getOpenFileName</code> 在PySide中返回一个元组。在移植PyQt代码时,这经常产生争论。比如: "bug 343":http://bugs.openbossa.org/show_bug.cgi?id=343.
'''NB:''' 由于API的改变,<code>QFileDialog.getOpenFileName</code> 在PySide中返回一个元组。在移植PyQt代码时,这经常产生争论。比如: [http://bugs.openbossa.org/show_bug.cgi?id=343 bug 343].


=== 新式(New-style)信号与槽有稍微不同的语法 (PSEP 100) ===
=== 新式(New-style)信号与槽有稍微不同的语法 (PSEP 100) ===
Line 50: Line 50:
</code>
</code>


如同在 "PSEP 100":http://www.pyside.org/docs/pseps/psep-0100.html 所描述的,使用 <code>QtCore.Signal()</code> 和 <code>QtCore.Slot()</code> 来代替。
如同在 [http://www.pyside.org/docs/pseps/psep-0100.html PSEP 100] 所描述的,使用 <code>QtCore.Signal()</code> 和 <code>QtCore.Slot()</code> 来代替。


如果你想修改你的 PyQt 代码使之使用 PySide 的命名规则,可以这样简单来实现:
如果你想修改你的 PyQt 代码使之使用 PySide 的命名规则,可以这样简单来实现:
Line 62: Line 62:
=== 使用稍有不同的语法完成Qt属性的声明 (PSEP 103) ===
=== 使用稍有不同的语法完成Qt属性的声明 (PSEP 103) ===


伴随上面信号与槽语法的修改,声明 Qt 的属性是通过 <code>QtCore</code>. Property 而不是 <code>QtCore.pyqtProperty</code> (见 "PSEP 103":http://www.pyside.org/docs/pseps/psep-0103.html)来完成的。
伴随上面信号与槽语法的修改,声明 Qt 的属性是通过 <code>QtCore</code>. Property 而不是 <code>QtCore.pyqtProperty</code> (见 [http://www.pyside.org/docs/pseps/psep-0103.html)来完成的。 PSEP 103]


=== 工具名称的差异 ===
=== 工具名称的差异 ===
Line 78: Line 78:
在PySide,不为在 Qt 4.5之前已经废弃的函数生成绑定代码。
在PySide,不为在 Qt 4.5之前已经废弃的函数生成绑定代码。


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


bug例子: "bug 359":http://bugs.openbossa.org/show_bug.cgi?id=359
bug例子: [http://bugs.openbossa.org/show_bug.cgi?id=359 bug 359]


举例来说,这会影响到 <code>QColor.dark()</code> 和 <code>QColor.light()</code> 函数,作为替代 <code>QColor.darker()</code> 和 <code>QColor.lighter()</code> 应当被使用。
举例来说,这会影响到 <code>QColor.dark()</code> 和 <code>QColor.light()</code> 函数,作为替代 <code>QColor.darker()</code> 和 <code>QColor.lighter()</code> 应当被使用。
Line 86: Line 86:
=== sender() 成员在 partial 或 lambda 函数内返回 None ===
=== sender() 成员在 partial 或 lambda 函数内返回 None ===


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


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


<code>
<code>
self.emit(SIGNAL (&amp;#39;text_changed_cb&amp;#39;), text)
self.emit(SIGNAL ('text_changed_cb'), text)
</code>
</code>


Line 119: Line 119:


<code>
<code>
self.emit(SIGNAL (&amp;#39;text_changed_cb(QString)'), text)
self.emit(SIGNAL ('text_changed_cb(QString)'), text)
</code>
</code>

Revision as of 11:53, 26 February 2018

This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

Attention: a port of PySide to Qt 5.x started in 2014, the progress and more details about this project can be found under PySide 2

En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh

PySide 与 PyQt 的差异

API 差异

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

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

from PyQt4.QtCore import *

import PyQt4.QtCore

而是必须像下面这样:

from PySide.QtCore import *

import PySide.QtCore

.

PySide 只支持 PyQt's "API 2" (PSEP 101)

PyQt 提供了 两套不同的 APIs , 第一套提供了

QStrings

,

QVariants

, 等作为Python类型。新的 API 2 提供了Qt类和python原生数据类型之间的自动转换,这样本质上也更Pythonic。PyQt 在 Python2.x 系列中默认是 API 1,而在 Python 3 中默认是 API 2。 PySide 只支持PyQt 的 API 2(详见 PSEP 101) 。因而Qt的类比如

QStrings

,

QStringLists

, 和

QVariants

在PySide不可用。作为替代,你应该使用原生的Python的数据类型。 如果你要从 PyQt 移植代码,你可能愿意先修改 PyQt 的代码使之使用 API 2(通过在导入 PyQt4 之前调用

sip.setapi(class,ver)

来实现),只有在修改的代码工作以后,修改导入部分来使用 PySide。 NB: 由于API的改变,

QFileDialog.getOpenFileName

在PySide中返回一个元组。在移植PyQt代码时,这经常产生争论。比如: bug 343.

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

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

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

如同在 PSEP 100 所描述的,使用

QtCore.Signal()

QtCore.Slot()

来代替。

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

QtCore.Signal = QtCore.pyqtSignal
QtCore.Slot = QtCore.pyqtSlot

.

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

伴随上面信号与槽语法的修改,声明 Qt 的属性是通过

QtCore

. Property 而不是

QtCore.pyqtProperty

(见 PSEP 103

工具名称的差异

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

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

功能性差异

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

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

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

bug例子: bug 359

举例来说,这会影响到

QColor.dark()

QColor.light()

函数,作为替代

QColor.darker()

QColor.lighter()

应当被使用。

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

如果一个lambda函数作为一个槽,

sender()

不能用来获取发送信号的对象。这在PyQt中是工作的,但是他们的实现在特定情况下行为不太正常。详见 bug 344

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

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

class Window(QtGui.QWidget):
 def ''init''(self, parent=None):
 super(QtGui.QWidget, self).''init''(parent)
 []

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

class Window(QtGui.QWidget):
 def ''init''(self, parent=None):
 super(Window, self).''init''(parent)
 []

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

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

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:

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