PySideとPyQtの差異
APIの差異
importする名前の違い(PyQt4の代わりにPySide)
PySideはライブラリ名がPyQtと違います。
from PyQt4.QtCore import *
や、
import PyQt4.QtCore
と書く代わりに、次のように書いてください。
from PySide.QtCore import *
import PySide.QtCore
PySideは、PyQtの"API 2"のみをサポートしています。(PSEP 101)
PyQtは2種類のAPIを提供しています[riverbankcomputing.co.uk]。
"API 1"は、Pythonに、QStrings, QVariants 等をそのまま(as is)提供しています。
新しい"API 2"は、Qtのクラスとそれに対応するPythonネイティブのデータ型の間の変換を提供しています。
また、API 2はよりPythonicです。Python 2.x 上のPyQtはAPI 1がデフォルトですが、Python 3上のPyQtはAPI 2がデフォルトです。
PySide は PyQtの API 2のみをサポートしています(詳細はPSEP 101 [pyside.org]を参照)。
そのため、QStrings, QStringLists, QVariants等のQtのクラスは、PySideでは使用できません。
代わりに、単にPythonネイティブのデータ型を使えばよいのです。
もし、コードをPyQtからPySideに移植するなら、まずPyQt用コードをAPI 2を使うように変更します(PyQt4をimportする前に、sip.setapi(class,ver)
を呼ぶように変更)。そして、作業完了後に、PySideをimportするように変更します。
NB: API変更のため、PySideではQFileDialog.getOpenFileName
はタプルを返します。
これはコードをPyQtから移植するときの問題点になるかもしれません(bug 343 [bugs.openbossa.org]などを参照)。
新スタイルのシグナル・スロットのシンタックスがわずかに違います (PSEP 100)
残念な事に、PyQtは 新スタイルのシグナル・スロットに 実装特有(implementation-specific 訳不安)な命名規則を、使用しています。
# Define a new signal called 'trigger' that has no arguments.
trigger = QtCore.pyqtSignal()
PSEP 100 [pyside.org]でも述べられているように、
PySideでは、QtCore.Signal()
and QtCore.Slot()
を代わりに使います。.
もしPyQt用のコードをPySideの命名規則に従うよう変更したいなら、簡単な定義をすればよいです。
QtCore.Signal = QtCore.pyqtSignal QtCore.Slot = QtCore.pyqtSlot
バインディングの機能の違い
Qt 4.5以前の非推奨の関数へのバインディングは提供されません。
PySideでは、Qt 4.5以前の非推奨の関数へのバインディングは提供されません。
もし、関数がPySideに無かった場合、Qt オンラインリファレンスドキュメント[doc.qt.nokia.com]
を参照して、その関数は非推奨ではないか、代わりにどの関数を使えばいいかを確認してください。
バグの例:bug 359 [bugs.openbossa.org]
この違いにより、例えば、QColor.dark()
と QColor.light()
の代わりに、
QColor.darker()
と QColor.lighter()
を使う必要が生じます。
sender() メソッドはpartialとlambda の中ではNoneを返します。
lambdaが スロットとして使用されら場合、シグナルを発信したオブジェクトを取得するためにsender()
を使う事は出来ません。
PyQtではsender()
を使う事が出来ますが、PyQtの実装はこの状況では正しく振る舞いません。
詳しくは bug 344 [bugs.openbossa.org] を参照。
クラスを継承したとき、必ず親クラスのコンストラクタを呼ばなくてはなりません
PyQtでは次のようなコードが許容されています。
class Window(QtGui.QWidget): def __init__(self, parent=None): super(QtGui.QWidget, self).__init__(parent) [...]
このコードでは、直接の親クラス(QtGui.QWidget)のコードは呼ばれません。
PySide では 正しいコードを書く事が求められます。
class Window(QtGui.QWidget): def __init__(self, parent=None): super(Window, self).__init__(parent) [...]