[PyQt] Qt message handler has wrong signature with Qt5

Baz Walter bazwal at ftml.net
Wed Apr 3 02:42:45 BST 2013

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, but
>> 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 &);


     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.

Baz Walter

More information about the PyQt mailing list