- The first thing to port is imports from PyQt4. Where ever you have a statement that look like:
Code:
from PyQt4.Qt import ...
change it to
Code:
try:
from PyQt4.Qt import ...
except ImportError:
from PyQt5.Qt import ...
If you use the QtCore or QtGui modules directly, change the imports like this.
Code:
try:
from PyQt4 import QtGui
except ImportError:
from PyQt5 import Qt as QtGui
- PyQt5 automatically converts QVariants to the equivalent python objects. So any code that explicitly converted QVariants will need to be ported. Look for function calls like: toBool(), toString(), toPyObject(), toInt(), etc.
To port these we use a utility function that will do the right thing regardless of Qt version.
Code:
try:
from calibre.gui2 import QVariant
del QVariant
except ImportError:
is_qt4 = False
convert_qvariant = lambda x: x
else:
is_qt4 = True
def convert_qvariant(x):
vt = x.type()
if vt == x.String:
return unicode(x.toString())
if vt == x.List:
return [convert_qvariant(i) for i in x.toList()]
return x.toPyObject()
Now replace any sites in your code that explicitly convert QVariants with a call to convert_qvariant(value) instead.
- The QString and QChar classes no longer exist in PyQt5. However, you should not have been using them in PyQt4 either. Simply replace their usage with the python unicode object. Any function call that expects QString will take a unicode object in both PyQt4 and PyQt5. Any Qt function that you call that returns a QString should simply be wrapped like this to work in both PyQt4 and PyQt5
Code:
ans = unicode(function_that_returns_a_qstring())
- The QAbstractItemModel class (and its various subclasses such as QListModel, QTreeModel and so on) no longer have a reset() method. If you use this method, replace it with beginResetModel() and endResetModel() which work with both Qt 4 and Qt 5
- The deprecated line edit with completion (MultiCompleteComboBox, MultiCompleteLineEdit) from calibre has been removed. If you use it replace it with EditWithComplete from calibre.gui2.complete2 (this works with both Qt 4 and Qt 5 and exists in all versions of calibre >=0.9.0).
- If you used the deprecated SIGNAL macro to connect Qt signals and slots, you will have to replace it with a new syntax, since it no longer exists in Qt 5. For example:
Code:
self.connect(action, SIGNAL("triggered()"), slot)
becomes
self.action.triggered.connect(slot)
The new syntax is nicer and more robust than the old and works in both Qt 4 and Qt 5
There are a few other, more obscure changes that might be needed, depending on what parts of Qt you use, which I will be happy to help with, if necessary.