[PyQt] QDesktopServices::setUrlHandler does not have the right types

Erick Tryzelaar idadesub at users.sourceforge.net
Thu Oct 2 01:58:38 BST 2008


We ran into some trouble trying to get QDesktopServices::setUrlHandler
and we tracked it down to a problem in pyqt4. setUrlHandler's source
ultimately calls invokeMethod, which we managed to get to work in
python, but we could only get setUrlHandler to work in c++. Looking at
the sip source, we saw that the interface was different:

static SIP_PYOBJECT invokeMethod(QObject *obj, const char *member, ...)

vs.

static void setUrlHandler(const QString &scheme, SIP_RXOBJ_CON
receiver, SIP_SLOT_CON(const QUrl &) method) [void (const QString
&scheme, QObject *receiver, const char *method)];

So, in python you use it like this:

QMetaObject.invokeMethod(o, "openUrl", Qt.DirectConnection, Q_ARG("QUrl", url))
QDesktopServices.setUrlHandler("foo", o, SLOT("openUrl"))
QDesktopServices.setUrlHandler("foo", o.openUrl)

So as an experiment, we modified the sip setUrlHandler interface to:

static void setUrlHandler(const QString &scheme, QObject *receiver,
const char *method);

And finally setUrlHandler worked, although it does have an ugly interface:

QDesktopServices.setUrlHandler("foo", o, "openUrl")


Finally, here's our test script if there's interest in another unit test:

from PyQt4.Qt import *

import sys

class Opener(QObject):
    @pyqtSignature("QUrl")
    def openUrl(self, url):
        print "url: ", url

    @pyqtSignature("")
    def doNuthzing(self):
        print "the goggles do this"

class App(QApplication):
    def __init__(self, argv):
        super(App, self).__init__(argv)

        url = QUrl("foo://bar/baz")

        o = Opener()
        print "qmo: ", QMetaObject.invokeMethod(o, "openUrl",
Qt.DirectConnection, Q_ARG("QUrl", url))

        mo = o.metaObject()
        for i in xrange(mo.methodCount()):
            m = mo.method(i)
            print m.signature(), m.tag(), m.methodType()

        QDesktopServices.setUrlHandler("foo", o, "openUrl")
        print 'foo URL opened: ',
QDesktopServices.openUrl(QUrl("foo://bar/baz"))

    def openUrl(self, url):
        print url

if __name__ == "__main__":
    app = App(sys.argv)


More information about the PyQt mailing list