Example #1
0
class Writer(QObject):
    def __init__(self, filename):
        QObject.__init__(self, None)
        self._filename = filename
        self._file = None
        self._dstream = None

    def __enter__(self):
        self.open()
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.close

    def open(self):
        self._file = QFile(self._filename)
        if not self._file.open(QIODevice.WriteOnly):
            raise ValueError("Cannot open " + self._filename)
        self._dstream = QDataStream(self._file)
        self._dstream.setVersion(QDataStream.Qt_4_5)
        for c in b"QGis.MemoryLayerData":
            self._dstream.writeUInt8(c)
        # Version of MLD format
        self._dstream.writeUInt32(2)

    def close(self):
        try:
            self._dstream.setDevice(None)
            self._file.close()
        except:  # noqa: E722
            pass
        self._dstream = None
        self._file = None

    def writeLayers(self, layers):
        for layer in layers:
            self.writeLayer(layer)

    def writeLayer(self, layer):
        if not self._dstream:
            raise ValueError("Layer stream not open for reading")
        ds = self._dstream
        dp = layer.dataProvider()
        ss = layer.subsetString()
        attr = dp.attributeIndexes()
        ds.writeQString(layer.id())
        ds.writeQString(ss)
        ds.writeInt16(len(attr))
        flds = dp.fields()  # noqa: F841
        fldnames = []
        for i in attr:
            fld = dp.fields()[i]
            fldnames.append(fld.name())
            ds.writeQString(fld.name())
            ds.writeInt16(int(fld.type()))
            ds.writeQString(fld.typeName())
            ds.writeInt16(fld.length())
            ds.writeInt16(fld.precision())
            ds.writeQString(fld.comment())

        layer.setSubsetString("")
        feats = layer.getFeatures()
        for feat in feats:
            ds.writeBool(True)
            if attr:
                for field in fldnames:
                    try:
                        ds.writeQVariant(feat[field])
                    except KeyError:
                        ds.writeQVariant(None)
            geom = feat.geometry()
            if not geom:
                ds.writeUInt32(0)
            else:
                wkb = geom.asWkb()
                ds.writeUInt32(len(wkb))
                ds.writeRawData(wkb)
        ds.writeBool(False)
        layer.setSubsetString(ss)
Example #2
0
class Reader(QObject):
    def __init__(self, filename):
        self._filename = filename
        self._file = None
        self._dstream = None
        self._version = None

    def __enter__(self):
        self.open()
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.close

    def open(self):
        self._file = QFile(self._filename)
        if not self._file.open(QIODevice.ReadOnly):
            raise ValueError("Cannot open " + self._filename)
        self._dstream = QDataStream(self._file)
        self._dstream.setVersion(QDataStream.Qt_4_5)
        for c in b"QGis.MemoryLayerData":

            ct = self._dstream.readUInt8()
            if ct != c:
                raise ValueError(self._filename +
                                 " is not a valid memory layer data file")
        version = self._dstream.readInt32()
        if version not in (1, 2):
            raise ValueError(
                self._filename +
                " is not compatible with this version of the MemoryLayerSaver plugin"
            )
        self._version = version

    def close(self):
        try:
            self._dstream.setDevice(None)
            self._file.close()
        except:  # noqa: E722
            pass
        self._dstream = None
        self._file = None

    def readLayers(self, layers):
        if not self._dstream:
            raise ValueError("Layer stream not open for reading")
        ds = self._dstream

        while True:
            if ds.atEnd():
                return
            id = ds.readQString()
            layer = None
            for l in layers:  # noqa: E741
                if l.id() == id:
                    layer = l
                    break
            if layer is None:
                self.skipLayer()
            else:
                self.readLayer(layer)

    def readLayer(self, layer):
        ds = self._dstream
        dp = layer.dataProvider()
        if dp.featureCount() > 0:
            raise ValueError("Memory layer " + id + " is already loaded")
        attr = dp.attributeIndexes()
        dp.deleteAttributes(attr)
        ss = ""
        if self._version > 1:
            ss = ds.readQString()
        nattr = ds.readInt16()
        attr = list(range(nattr))
        for i in attr:
            name = ds.readQString()
            qtype = ds.readInt16()
            typename = ds.readQString()
            length = ds.readInt16()
            precision = ds.readInt16()
            comment = ds.readQString()
            fld = QgsField(name, qtype, typename, length, precision, comment)
            dp.addAttributes([fld])

        nullgeom = QgsGeometry()
        fields = dp.fields()
        while ds.readBool():
            feat = QgsFeature(fields)
            for i in attr:
                value = ds.readQVariant()
                if value is not None:
                    feat[i] = value

            wkbSize = ds.readUInt32()
            if wkbSize == 0:
                feat.setGeometry(nullgeom)
            else:
                geom = QgsGeometry()
                geom.fromWkb(ds.readRawData(wkbSize))
                feat.setGeometry(geom)
            dp.addFeatures([feat])
        layer.setSubsetString(ss)
        layer.updateFields()
        layer.updateExtents()

    def skipLayer(self):
        ds = self._dstream
        nattr = ds.readInt16()
        attr = list(range(nattr))
        for i in attr:
            name = ds.readQString()  # noqa: F841
            qtype = ds.readInt16()  # noqa: F841
            typename = ds.readQString()  # noqa: F841
            length = ds.readInt16()  # noqa: F841
            precision = ds.readInt16()  # noqa: F841
            comment = ds.readQString()  # noqa: F841
        while ds.readBool():
            for i in attr:
                ds.readQVariant()
            wkbSize = ds.readUInt32()
            if wkbSize > 0:
                ds.readRawData(wkbSize)
Example #3
0
class Client(QDialog):
    def __init__(self, parent: QWidget = None):
        super().__init__(parent)

        self._in = QDataStream()
        self.blockSize = 0

        self.currentFortune = ""

        self.hostLineEdit = QLineEdit("fortune")
        self.getFortuneButton = QPushButton(self.tr("Get Fortune"))
        self.statusLabel = QLabel(
            self.
            tr("This examples requires that you run the Local Fortune Server example as well."
               ))
        self.socket = QLocalSocket(self)

        self.setWindowFlags(self.windowFlags()
                            & ~Qt.WindowContextHelpButtonHint)
        hostLabel = QLabel(self.tr("&Server name:"))
        hostLabel.setBuddy(self.hostLineEdit)

        self.statusLabel.setWordWrap(True)

        self.getFortuneButton.setDefault(True)
        quitButton = QPushButton(self.tr("Quit"))

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self._in.setDevice(self.socket)
        self._in.setVersion(QDataStream.Qt_5_10)

        self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton)

        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.socket.readyRead.connect(self.readFortune)
        self.socket.errorOccurred.connect(self.displayError)

        mainLayout = QGridLayout(self)
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostLineEdit, 0, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)

        self.setWindowTitle(QGuiApplication.applicationDisplayName())
        self.hostLineEdit.setFocus()

    @pyqtSlot()
    def requestNewFortune(self):
        self.getFortuneButton.setEnabled(False)
        self.blockSize = 0
        self.socket.abort()
        self.socket.connectToServer(self.hostLineEdit.text())

    @pyqtSlot()
    def readFortune(self):
        if self.blockSize == 0:
            # Relies on the fact that QDataStream serializes a quint32 into
            # sizeof(quint32) bytes
            if self.socket.bytesAvailable() < 4:  #  (int)sizeof(quint32))
                return
            self.blockSize = self._in.readUInt32()

        if self.socket.bytesAvailable() < self.blockSize or self._in.atEnd():
            return

        nextFortune = ""
        nextFortune = self._in.readQString()

        if nextFortune == self.currentFortune:
            QTimer.singleShot(0, self.requestNewFortune)
            return

        currentFortune = nextFortune
        self.statusLabel.setText(currentFortune)
        self.getFortuneButton.setEnabled(True)

    @pyqtSlot(QLocalSocket.LocalSocketError)
    def displayError(self, socketError):
        if socketError == QLocalSocket.ServerNotFoundError:

            QMessageBox.information(
                self,
                self.tr("Local Fortune Client"),
                self.tr("The host was not found. Please make sure "
                        "that the server is running and that the "
                        "server name is correct."),
            )
        elif socketError == QLocalSocket.ConnectionRefusedError:
            QMessageBox.information(
                self,
                self.tr("Local Fortune Client"),
                self.tr("The connection was refused by the peer. "
                        "Make sure the fortune server is running, "
                        "and check that the server name is correct."),
            )
        elif socketError == QLocalSocket.PeerClosedError:
            return
        else:
            QMessageBox.information(
                self,
                self.tr("Local Fortune Client"),
                self.tr("The following error occurred: %s." %
                        (self.socket.errorString())),
            )

        self.getFortuneButton.setEnabled(True)

    @pyqtSlot()
    def enableGetFortuneButton(self):
        self.getFortuneButton.setEnabled(bool(self.hostLineEdit.ext()))