Skip to content
  • 0 Votes
    8 Posts
    516 Views
    JonBJ

    @Narutoblaze
    Your code/algorithm is incorrect. This is basic coding, please study what your code does. You "actively" encourage reading across file boundaries, i.e. what you call "too much").

    You (seem to) start by setting size to the total number of bytes expected for the file. Then you call read(buffer, size);. But when that returns with fewer bytes than size you still call it again next time round asking it to read up to size further bytes. This can/will exceed the number of bytes in the first file. You obviously need to reduce what size you pass to read() accordingly on subsequent calls. And then be careful what you compare in your if (... || numReadTotal == size). Adjust your code however to make it right.

    I previously said that the whole synchronous approach of repeatedly calling waitForReadyRead() in a loop is not the event-driven way to do things. Allow bytes to arrive in repeated readyRead() signals asynchronously instead.

  • 0 Votes
    8 Posts
    374 Views
    JonBJ

    @CJha
    It does seem wasteful to store this "streaming attribute" in your objects' data class. If there are a million objects, why have a million bools in them to tell them what to do if it's all supposed to be the same? Not to mention, what would happen if some objects' boolean said to stream all information and some did not? And you don't want to have to change something inside each object every time you want to stream with or without the "actual data part". That's why it feels like an attribute on the QDataStream rather than on the objects. Maybe you can have a static function on the objects to return your information instead of actual storage in each instance.

  • 0 Votes
    10 Posts
    443 Views
    D

    @Christian-Ehrlicher Hmmm I'm not having any luck with this method so far :/
    Code below is self contained test. The DataStream is not commitTransaction and thus still waits for more data but never reads it/deals with it.
    Socket dies, no more data comes in, handle_ready_read never gets called again, even if I force call again it wont read any more data... :/ Where am I hitting wall here?

    import json import uuid from functools import partial from PySide2.QtNetwork import * from PySide2.QtCore import * from PySide2.QtWidgets import * class BasicServer(QTcpServer): s_newJob = Signal(object) def __init__(self, port: int): QTcpServer.__init__(self) self._mStatus = self.listen(QHostAddress.LocalHost, port) self._mSocketList = {} self._mJobs = {} self.newConnection.connect(self._handleNewConnection) print("Starting logic server on port : ", port, " Status : ", self._mStatus) self._mTimer = QElapsedTimer() self._mTimer.start() def getStatus(self) -> int: return self._mStatus def _handleNewConnection(self): client_socket: QTcpSocket = self.nextPendingConnection() client_socket.readyRead.connect(partial(self.handle_ready_read, client_socket)) stream = QDataStream(client_socket) self._mSocketList[client_socket] = [stream, QByteArray()] client_socket.disconnected.connect(partial(self._handleSocketDisconnect, client_socket)) def handle_ready_read(self, client_socket): streamItem = self._mSocketList.get(client_socket, None) if streamItem is None: return print("reading?") stream = streamItem[0] stream.startTransaction() streamData = streamItem[1] stream >> streamData print(len(streamData)) self._mSocketList[client_socket][1] = streamData if not stream.commitTransaction(): return print("IM FINISH! ", streamData) def _handleSocketDisconnect(self, socketPtr: QTcpSocket): print("Socket is gone...") return # for now keep socket "alive" killPort = socketPtr.peerPort() if killPort in self._mJobs: if not self._mJobs[killPort]["emitted"]: if self._mJobs[killPort]["toDownload"] == 0: pass del self._mJobs[killPort] if socketPtr in self._mSocketList: del self._mSocketList[socketPtr] print("Killing socket", killPort, socketPtr) socketPtr.deleteLater() def clientTest(): port = 500 socket = QTcpSocket() # Connect to the server socket.connectToHost("localhost", port) msg = str(uuid.uuid4()) for a in range(0, 10): msg += msg print(len(msg) / 1024 / 1024) # Wait for the connection to be established if socket.waitForConnected(5000): print("sending...") # Create a QByteArray to hold the data data = QByteArray("Hello World!".encode()) jDumped = json.dumps({"hello": "world", "this": [{"this": "is"}, {"awe": "some"}], "stupidLongStuff": msg, "END": 1}) data = QByteArray(jDumped.encode()) # Create a QDataStream to write the data stream = QDataStream(socket) # stream.setVersion(QDataStream.Qt_5_15) print("Data size : ", len(data)) stream << data # stream.writeString("hellooo") # dataSize = len(data) # print("sending data size : ", dataSize) # Write the data to the stream # stream.writeInt64(dataSize) # socket.waitForBytesWritten() # socket.write(struct.pack("l", len(data))) # socket.write(data.encode()) socket.waitForBytesWritten() print("Data sent successfully") else: print("Error:", socket.errorString()) app = QApplication([]) s = BasicServer(500) clientTest() app.exec_()
  • 0 Votes
    11 Posts
    868 Views
    K

    I made a rudimentary solution for the problem.

    //Read data to QString with a known length void readDataQString(QDataStream &ds, QString &str, uint length) { QByteArray buffer(length,Qt::Uninitialized); ds.readRawData(buffer.data(),length); str = QString(buffer); qInfo() << str; } //Write data from QString without length info void writeDataQString(QDataStream &ds, QString &str) { QByteArray ab = str.toUtf8(); for(int i = 0; i < ab.size(); ++i) { quint8 int_8 = static_cast<quint8>(ab.at(i)); ds << int_8; } QBuffer *internalBuffer = qobject_cast<QBuffer*>(ds.device()); QByteArray ba = internalBuffer->buffer(); qInfo() << ba.toHex(':'); }

    I hope this works for everyone.

  • 0 Votes
    6 Posts
    482 Views
    SGaistS

    When you use custom types, it's pretty usual to register them all before building any of the widgets that will use them as part of your application startup sequence after you created your QApplication object.

  • 0 Votes
    3 Posts
    630 Views
    K

    @Christian-Ehrlicher Yup, it worked! Thanks a lot.

  • 0 Votes
    46 Posts
    9k Views
    jsulmJ

    @CJha said in How to write entire QVector to a binary file?:

    If it's a copy then I assume it is always going to be the data

    No, because Qt containers use copy-on-write. See https://doc.qt.io/qt-5/implicit-sharing.html

  • 0 Votes
    2 Posts
    438 Views
    J

    Now I realized I have to set QDataStream::setVersion to QDataStream::Qt_4_7. I think the problem is solved.

  • 0 Votes
    16 Posts
    2k Views
    hskoglundH

    Maybe that QByteArray is the culprit, you could try rewrite into more vanilla standard:

    ... { QByteArray block; QBuffer buffer(&block); buffer.open(QIODevice::WriteOnly); QDataStream out(&buffer); ...

    at least you would expose more stuff to the debugger :-)

  • 0 Votes
    3 Posts
    902 Views
    D

    @jsulm said in QDataStream an openCV::mat serialisation...:

    @Dariusz What is stream here? Is it QDataStream?
    "Any idea what did I mess up with this ?" - well, what is not working?

    Yep :- )

    I think I might "got it". Naturally 5 min after asking question... elemSize1() return incorrect number of channels. Looks like I need elemSize() instead. still testing.

    Yep it was wrong element number.

    Hope it helps other "serializers" out here : -)

  • 0 Votes
    5 Posts
    2k Views
    E

    Adding typedef typename Container::value_type valType; to the loop helped with this issue . Thank you very much .

  • 0 Votes
    12 Posts
    4k Views
    J

    @raven-worx @mrjj @Wieland @Pablo-J-Rogina
    Thank you guys !
    It worked perfectly. I'm now able to read and write a XML file and load items to my drawing.

    Thank you again
    Happy coding !

  • 0 Votes
    5 Posts
    3k Views
    K

    Thanks @karlheinzreichel

    Originaly I have data called Sample, to save it I save it as a QVector<double> const Value.

    for(int iSamples=0;iSamples<_pSampleProcessing->getRawDataVector().size();iSamples++)
    {
    xDataVector.append(_pSampleProcessing->getRawDataVector().at(iSamples).getX());
    yDataVector.append(_pSampleProcessing->getRawDataVector().at(iSamples).getY());
    }

    I dont think so, because If it would be overloaded I might get an error, because I tried it to save it as a Sample before. So saving as a double seems possible.

  • 0 Votes
    3 Posts
    11k Views
    B

    I've posted an answer how to know if you have read everything here: https://stackoverflow.com/a/46162082/969016

  • 0 Votes
    6 Posts
    2k Views
    M

    Another solution: Store all your data as key-value pairs in QMap<QString, QVariant> and write it to QDataStream. Next, applications will read full QMap contents from stream, then access needed values by their names.

  • QDataStream pack and unpack

    Unsolved General and Desktop
    5
    0 Votes
    5 Posts
    2k Views
    kshegunovK

    @VRonin, division by 2, really? I know you can do much better ;)

    while (data) { const quint8 byte = data & 1; // data % 2 data >>= 1; // data / 2 myStream.writeRawData(&byte, 1); }
  • 0 Votes
    1 Posts
    1k Views
    No one has replied
  • 0 Votes
    2 Posts
    2k Views
    SGaistS

    Hi,

    There's no ready made code to dump your model since only you know what make sense to dump. So yes you'll have to write the dumper and loader yourself. QDataStream comes to mind for that task.

    Hope it helps

  • 0 Votes
    2 Posts
    2k Views
    S

    Ok guy thank you for that much replies :P! I solved the issue by myself anyway. In case sombebody has a similar problem here comes the solution:

    What I did wrong was that I connected a time consuming function to the UpdateClient::tcpReady() slot. In this function I did some stuff which also lead to the emission of UpdateClient::tcpReady(). This broke the QEventQueue. So to what I had to chance was to skip the direct signal slot connection an do this in the UpdateClient::tcpReady():

    QTimer::singleShot(0, this, SIGNAL(updateAvailable()));

    No everything is working fine ;).

  • 0 Votes
    2 Posts
    2k Views
    A

    I am not sure I completely understand the problem since
    I do not see any structure in your read/write code.

    But normal way to deal with structures (the same as with classes)
    is to write/read every member separate in their natural form with provided by QDataStream functionality.
    And you certainly need to know type of the data written to the file to read it properly.
    Your problem (as far as I can understand) is related to using wrong function to read integer data,
    cause you read it as char data,