[PyQt] Qt message handler has wrong signature with Qt5

Phil Thompson phil at riverbankcomputing.com
Tue Apr 9 15:40:29 BST 2013

On Wed, 03 Apr 2013 02:42:45 +0100, Baz Walter <bazwal at ftml.net> wrote:
> On 03/04/13 01:17, Phil Thompson wrote:
>> On Wed, 03 Apr 2013 00:16:49 +0100, Baz Walter <bazwal at ftml.net> wrote:
>>> Hello
>>> For Qt4, QtCore.qInstallMsgHandler installs a Qt message handler with
>>> the following signature:
>>>       void myMsgHandler(QtMsgType, const char *);
>>> Using PyQt4 with Qt4, this correctly results in the second argument
>>> being passed as a python bytes object (for both the v1 and v2 apis).
>>> However, for Qt5 it only does this when using Python3 with the v2 api.
>>> For Python3 with the v1 api, it passes a QString, and for Python2 it
>>> either passes a QString (v1 api) or a python unicode object (v2 api).
>>> I realize that QtCore.qInstallMsgHandler has been deprecated in Qt5,
>>> it would still be great if this could be fixed at some point.
>>> Simple test script:
>>>       import sys, sip
>>>       sip.setapi('QString', int(sys.argv[1]) if sys.argv[1:] else 1)
>>>       from PyQt4 import QtGui, QtCore
>>>       app = QtGui.QApplication([])
>>>       def handler(kind, msg):
>>>           print('API v%s: %s, %s' % (
>>>               sip.getapi('QString'), type(kind), type(msg)))
>>>       QtCore.qInstallMsgHandler(handler)
>>>       app.desktop().screenGeometry(None)
>> As the Qt5 message handler is passed a QString rather than the Qt4 char
>> I think the current behaviour is the right one. Qt5 is not Qt4 so PyQt4
>> built against Qt5 is not going to have the same API as PyQt4 built
>> against
>> Qt4.
> No, the Qt5 message handler is also passed a const char *.
> There are two versions of the Qt message handler in Qt5:
>      void myMessageHandler(QtMsgType, const QMessageLogContext &, const 
> QString &);
> and
>      void myMsgHandler(QtMsgType, const char *);
> The second one is deprecated, and I would argue that there is not much 
> point in supporting transitional apis like this if they don't match the 
> original signature. If they do match, it makes it a lot easier to 
> maintain a single (transitional) PyQt4 code-base that runs on both Qt4 
> and Qt5.
> But in any case, PyQt's current treatment of this api is inconsistent: 
> for Qt5, it passes a bytes object with the Python3 v2 api, and otherwise

> passes either a QString or unicode object. So there is something amiss 
> with the current behaviour, whichever way you look at it.

It's actually taking advantage of the extra encoding information that Qt5
provides. I've changed it so that the behaviour is the same (modulo Python
version and API version) for Qt4 and Qt5.


More information about the PyQt mailing list