Differences Between PySide and PyQt/zh: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 1: Line 1:
'''简体中文''' [[Differences-Between-PySide-and-PyQt|English]]<br />
[[Category:LanguageBindings::PySide]]<br />[[Category:SimplifiedChinese::LanguageBindings::PySide]]<br />'''简体中文''' [[Differences Between PySide and PyQt|English]]<br />[toc align_right=&quot;yes&amp;quot; depth=&quot;3&amp;quot;]


=PySide 与 PyQt 的差异=
= PySide 与 PyQt 的差异 =


==<span class="caps">API</span> 差异==
== API 差异 ==


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


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


或<br />
<code><br />from PyQt4.QtCore import *<br /></code><br />或<br /><code><br />import PyQt4.QtCore<br /></code>


而是必须像下面这样:
而是必须像下面这样:


或<br /> .
<code><br />from PySide.QtCore import *<br /></code><br /><br /><code><br />import PySide.QtCore<br /></code><br />.


===PySide 只支持 PyQt’s “<span class="caps">API</span> 2” (<span class="caps">PSEP</span> 101)===
=== PySide 只支持 PyQt's &quot;API 2&amp;quot; (PSEP 101) ===


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


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


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


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


===新式(New-style)信号与槽有稍微不同的语法 (<span class="caps">PSEP</span> 100)===
=== 新式(New-style)信号与槽有稍微不同的语法 (PSEP 100) ===


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


如同在 [http://www.pyside.org/docs/pseps/psep-0100.html <span class="caps">PSEP</span> 100] ''[pyside.org]'' 所描述的,使用 <code>QtCore.Signal()</code> <code>QtCore.Slot()</code> 来代替。
<code><br /># 定义一个叫做 'trigger' 的没有参数的新的信号<br />trigger = QtCore.pyqtSignal()<br /></code>
 
如同在 &quot;PSEP 100&amp;quot;:http://www.pyside.org/docs/pseps/psep-0100.html 所描述的,使用 &lt;code&amp;gt;QtCore.Signal()&lt;/code&amp;gt; &lt;code&amp;gt;QtCore.Slot()&lt;/code&amp;gt; 来代替。


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


.
<code><br />QtCore.Signal = QtCore.pyqtSignal<br />QtCore.Slot = QtCore.pyqtSlot<br /></code><br />.


===使用稍有不同的语法完成Qt属性的声明 (<span class="caps">PSEP</span> 103)===
=== 使用稍有不同的语法完成Qt属性的声明 (PSEP 103) ===


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


===工具名称的差异===
=== 工具名称的差异 ===


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


* pyuic4 -&gt; pyside-uic
* pyuic4 <s>&gt; pyside-uic<br />* pyrcc4</s>&gt; pyside-rcc4
* pyrcc4 -&gt; pyside-rcc4
* pylupdate4 -&gt; pyside-lupdate
* pylupdate4 -&gt; pyside-lupdate


==功能性差异==
== 功能性差异 ==


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


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


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


bug例子: [http://bugs.openbossa.org/show_bug.cgi?id=359 bug 359] ''[bugs.openbossa.org]''
bug例子: &quot;bug 359&amp;quot;:http://bugs.openbossa.org/show_bug.cgi?id=359


举例来说,这会影响到 <code>QColor.dark()</code> <code>QColor.light()</code> 函数,作为替代 <code>QColor.darker()</code> <code>QColor.lighter()</code> 应当被使用。
举例来说,这会影响到 &lt;code&amp;gt;QColor.dark()&lt;/code&amp;gt; &lt;code&amp;gt;QColor.light()&lt;/code&amp;gt; 函数,作为替代 &lt;code&amp;gt;QColor.darker()&lt;/code&amp;gt; &lt;code&amp;gt;QColor.lighter()&lt;/code&amp;gt; 应当被使用。


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


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


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


在一些情况下 PyQt 允许这样的代码:
在一些情况下 PyQt 允许这样的代码:
<code><br />class Window(QtGui.QWidget):<br /> def ''init''(self, parent=None):<br /> super(QtGui.QWidget, self).''init''(parent)<br /> […]<br /></code>


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


===旧式风格的信号需要使用圆括号===
<code><br />class Window(QtGui.QWidget):<br /> def ''init''(self, parent=None):<br /> super(Window, self).''init''(parent)<br /> […]<br /></code>
 
=== 旧式风格的信号需要使用圆括号 ===


PyQt allows use o short-circuit signals without parentheses such as:
PyQt allows use o short-circuit signals without parentheses such as:
<code><br />self.emit(SIGNAL (&amp;#39;text_changed_cb&amp;#39;), text)<br /></code>


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:
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:


You can check the complete discussion on [http://bugs.pyside.org/show_bug.cgi?id=314 bug #314] ''[bugs.pyside.org]''
<code><br />self.emit(SIGNAL (&amp;#39;text_changed_cb(QString)'), text)<br /></code>
 
===Categories:===
 
* [[:Category:LanguageBindings|LanguageBindings]]
** [[:Category:LanguageBindings::PySide|PySide]]
* [[:Category:SimplifiedChinese|SimplifiedChinese]]
** [[:Category:SimplifiedChinese::LanguageBindings|LanguageBindings]]
*** [[:Category:SimplifiedChinese::LanguageBindings::PySide|PySide]]

Revision as of 09:28, 24 February 2015



简体中文 English
[toc align_right="yes&quot; depth="3&quot;]

PySide 与 PyQt 的差异

API 差异

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

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

<br />from PyQt4.QtCore import *<br />



<br />import PyQt4.QtCore<br />

而是必须像下面这样:

<br />from PySide.QtCore import *<br />



<br />import PySide.QtCore<br />


.

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

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

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

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

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

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

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

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

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

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

<br />QtCore.Signal = QtCore.pyqtSignal<br />QtCore.Slot = QtCore.pyqtSlot<br />


.

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

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

工具名称的差异

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

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

功能性差异

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

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

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

bug例子: "bug 359&quot;:http://bugs.openbossa.org/show_bug.cgi?id=359

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

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

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

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

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

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

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

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

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

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

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

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:

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