PyQt4和PyQt5之间的差异¶
PyQt5 不兼容 PyQt4 (尽管事实证明将程序从PyQt4移植到PyQt5并不困难). 本节描述了两者之间的主要差异.
支持的Python版本¶
仅支持Python2.6以后的版本
弃用的功能¶
PyQt5不支持在Qt v5.0中被标记为弃用或废弃的Qt API的任何部分。然而,其中一些可能偶然包含在内。这些被认为是错误,如果发现将被删除。
Multiple APIs¶
PyQt4 supports a number of different API versions (QString
, QVariant
etc.). 除QVariant
外,PyQt5仅为所有版本的Python实现了这些API的v2。The changed support for QVariant
, including the removal of QPyNullVariant
, is described in Support for QVariant.
旧式信号和槽¶
PyQt4’s old-style signals and slots are not supported. Therefore the following are not implemented in PyQt5:
QObject.connect()
QObject.emit()
SIGNAL()
SLOT()
All methods that had arguments that are usually the results of calls to SIGNAL()
or SLOT()
are no longer supported. There will always be an equivalent that takes a bound signal or callable respectively.
In addition the following methods have differences:
disconnect()
takes no arguments and disconnects all connections to theQObject
instance.
新式信号和插槽¶
Qt将带有可选参数的信号作为两个独立的信号来实现,一个带有参数,另一个没有参数。PyQt4 exposed both of these allowing you to connect to each of them. 但是,在发射信号时,必须使用适合发射参数数量的信号。
PyQt5只显示所有参数被指定的信号。但是,它允许在发送信号时省略任何可选参数。
与PyQt4不同,PyQt5支持从QObject
(即在mixin中)未分类的类中的属性,信号和时隙的定义。
QtDeclarative
,QtScript
和QtScriptTools
模块¶
不支持PyQt4的QtDeclarative
,QtScript
和QtScriptTools
模块。这些已被PyQt5的QtQml
和QtQuick
模块取代。与PyQt4不同,PyQt5支持从QML创建Python对象。
QtGui
模块¶
PyQt4的QtGui
模块已被分割为PyQt5的QtGui
,QtPrintSupport
和QtWidgets
模块。
QtOpenGL
模块¶
PyQt5仅支持QGLContext
,QGLFormat
和QGLWidget
类。
QtWebKit
模块¶
PyQt4’s QtWebKit
module has been split into PyQt5’s QtWebKit
and QtWebKitWidgets
modules.
pyqtconfig
模块¶
PyQt4’s pyqtconfig
module is not supported. The section The PyQt5 Extension API describes the support that PyQt5 provides to third-party packages (e.g. QScintilla) that want to build on top of PyQt5.
QDataStream
¶
The readUInt8()
, readInt8()
, writeUInt8()
and writeInt8()
methods all interpret the values being read and written as numeric values. In PyQt4 they are interpreted as single character strings.
QFileDialog
¶
The getOpenFileNameAndFilter()
, getOpenFileNamesAndFilter()
and getSaveFileNameAndFilter()
methods of PyQt4’s QFileDialog
have now been renamed getOpenFileName()
, getOpenFileNames()
and getSaveFileName()
respectively in PyQt5. PyQt4’s implementations of getOpenFileName()
, getOpenFileNames()
and getSaveFileName()
are not supported in PyQt5.
QGraphicsItemAnimation
¶
Support for the deprecated QGraphicsItemAnimation
class has been removed. If porting an existing PyQt4 application then consider first updating it to use QPropertyAnimation
instead.
QMatrix
¶
Support for the deprecated QMatrix
class has been removed. If porting an existing PyQt4 application then consider first updating it to use QTransform
instead.
QPyTextObject
¶
PyQt4 implements the QPyTextObject
as a workaround for the inability to define a Python class that is sub-classed from more than one Qt class. PyQt5 does support the ability to define a Python class that is sub-classed from more than one Qt class so long as all but one of the Qt classes are interfaces, i.e. they have been declared in C++ as such using Q_DECLARE_INTERFACE
. Therefore QPyTextObject
is not implemented in PyQt5.
QSet
¶
In PyQt4, QSet
was implemented as a list in Python v2 and a set in Python v3. In PyQt5 QSet
is always implemented as a set.
pyuic5
¶
pyuic5 does not support the --pyqt3-wrapper
flag of pyuic4
.
pyrcc5
¶
pyrcc5 does not support the -py2
and -py3
flags of pyrcc4
. The output of pyrcc5 is compatible with all versions of Python starting with Python v2.6.
Cooperative Multi-inheritance¶
与PyQt4不同,PyQt5类实现了协作式多重继承。换句话说,PyQt5类在它们的__ init __
方法中(其中kwds
是未使用的关键字参数的字典)总是与以下Python v3代码等效:
super().__init__(**kwds)
这意味着这些未使用的关键字参数被传递给任何mixin类的__ init __
方法。这些mixin类必须合作,即如果他们有自己的__ init __
实现,他们必须进行类似的调用。
在PyQt4中使用多重继承时,通常会显式调用超类的__ init __
方法,例如:
class MyQObject(QObject, MyMixin):
def __init__(self, parent, mixin_arg):
QObject.__init__(self, parent)
MyMixin.__init__(self, mixin_arg)
# Other initialisation...
在PyQt5中,上面的代码会导致MyMixin .__ init __
被调用两次。相反,它应该实施如下:
class MyQObject(QObject, MyMixin):
def __init__(self, **kwds):
super().__init__(**kwds)
# Other initialisation...
Note that if there is no other initialisation to do then the __init__
method isn’t actually needed.
The mixin class should be implemented as follows:
class MyMixin:
def __init__(self, mixin_arg, **kwds):
super().__init__(**kwds)
# Other initialisation...
If a class only inherits from a single class then it can still call the super-class’s __init__
method explicitly (although it is recommended to use super()
).
Releasing the GIL¶
The GIL is only released when it is known to be needed. PyQt4 always released the GIL when calling Qt.
退出时对象销毁¶
When the Python interpreter exits PyQt4 (by default) calls the C++ destructor of all wrapped instances that it owns. This happens in a random order and can therefore cause the interpreter to crash. This behavior can be disabled by calling the sip.setdestroyonexit()
function. PyQt5 always calls sip.setdestroyonexit()
automatically.