[PyQt] send a QVariant in a QUdpSocket Datagram?

emmanuel_mayssat at lynceantech.com emmanuel_mayssat at lynceantech.com
Thu Aug 25 00:55:05 BST 2011


Hello,

I have been able to send a QVariant in over the network using a QTcpSocket and QDataStream.
now I would like to send the same QVariant over a QUdpSocket.

The issue is that the type of a datagram is string or QByteArray (Not QDataStream)
So I send my datagram as a QByteArray

    def issuePyObject(self, pyobject):
        ''' Note that an Item needs to of class object and not class QObject !!! '''


        self.request = QByteArray()
        stream = QDataStream(self.request, QIODevice.WriteOnly)
        stream.setVersion(QDataStream.Qt_4_2)
        stream.writeUInt16(0)
        qVariant = QVariant(pyobject)
        if self.debug:
            print pyobject
            print qVariant.toPyObject()    # <-- Works because it knows the qVariant type (class!!)
            # Indeed it uses the correct __str__ rountine!!!
        stream.writeQVariant(qVariant)
        stream.device().seek(0)
        nextBlockSize = self.request.size() - SIZEOF_UINT16
        if self.debug: print "nextBlockSize = %d " % nextBlockSize
        stream.writeUInt16(nextBlockSize)


        if self.protocol == 'udp' :
            self.udpSocket = QUdpSocket()
            datagram = self.request
            self.udpSocket.bytesWritten.connect(self.on_udpSocket_bytesWritten)
            self.udpSocket.writeDatagram(datagram, QHostAddress(QHostAddress.Broadcast),
self.portNumber)
        elif self.protocol == 'tcp':
            self.tcpSocket = QTcpSocket()
            self.connect(self.tcpSocket, SIGNAL("connected()"), self.on_tcpSocket_connected)
            self.connect(self.tcpSocket, SIGNAL("disconnected()"), self.on_tcpSocket_disconnected)
            self.connect(self.tcpSocket, SIGNAL("readyRead()"), self.on_tcpSocket_readyRead)
            self.connect(self.tcpSocket, SIGNAL("error(QAbstractSocket::SocketError)"),
self.on_tcpSocket_error)
            self.connect(self.tcpSocket, SIGNAL("hostFound()"), self.on_tcpSocket_hostFound)
            if self.tcpSocket.isOpen():
                self.tcpSocket.close()
            self.tcpSocket.connectToHost(self.serverName, self.portNumber)
        else:
            pass

Now on the server side i have to convert the datagram into a QVariant and then the PyObject
This operation doesn't work at all !!!
As a matter of fact even reading nextBlockSize is incorrect!

    @LInAndOut(DEBUG & THREADS)
    def run(self):
        if self.debug: print "UDP Server on %d" % self.portNumber
        udpSocket = QUdpSocket()
        udpSocket.bind(self.portNumber)
        udpSocket.readyRead.connect(self.on_udpSocket_readyRead)
        while(udpSocket.state()==QAbstractSocket.BoundState):
            udpSocket.waitForReadyRead(-1)
            while udpSocket.hasPendingDatagrams():
                datagram, host, port = udpSocket.readDatagram(udpSocket.pendingDatagramSize())
                if self.debug: print "Received datagram: \"%s\"" % datagram
                self.extractNotificationFromDatagram(datagram)


    @LInAndOut(DEBUG & THREADS)
    def extractNotificationFromDatagram(self,datagram):
        notification = LNotificationItem()
        stream = QDataStream(QByteArray(datagram),QIODevice.ReadOnly)
        stream.setVersion(QDataStream.Qt_4_2)
        nextBlockSize = stream.readUInt16()
        qVariant = stream.readQVariant()
        notification =  qVariant.toPyObject()

        if self.debug :
            print qVariant
            #print qVariant.toPyObject() # doesn't work !!!! Check SIP !!!
            print "notification: %s" %  notification     # <-- WORKS !
            print "nextBlockSize: %d" %  nextBlockSize     # <-- WORKS !

        try:
            LThread.lock.lockForWrite()
            try:
                self.parent().dataContainer.notifications.append(notification)
                self.parent().dataContainer.timeLastWritten = time.time()
            except AttributeError, e:
                print notification
        finally:
            LThread.lock.unlock()

Please help!

-- 
Emmanuel


More information about the PyQt mailing list