Results 1 to 6 of 6

Thread: when QBuffer emits readyRead signal?

  1. #1
    Join Date
    May 2009
    Posts
    75
    Thanks
    5
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default when QBuffer emits readyRead signal?

    Hi

    Reading QBuffer documentation:
    QBuffer emits readyRead() when new data has arrived in the buffer.
    The question is: how new data can arrive in the buffer?
    I mean, I declared a QBuffer:
    Qt Code:
    1. QByteArray byteArray;
    2. QBuffer buffer(&byteArray);
    3. buffer.open(QIODevice::ReadWrite);
    To copy to clipboard, switch view to plain text mode 
    In my thought new data is considered arrived if I write data in the byteArray directly:
    Qt Code:
    1. byteArray.append("hallo");
    To copy to clipboard, switch view to plain text mode 
    but readyRead() is never called

    so how new data can arrive in the buffer to make readyRead() be emitted?

    best reagards
    Max

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: when QBuffer emits readyRead signal?

    I think you misunderstand how the QBuffer / QByteArray relationship works. As the docs say:

    The QBuffer class provides a QIODevice interface for a QByteArray.
    ...
    QBuffer allows you to access a QByteArray using the QIODevice interface. The QByteArray is treated just as a standard random-accessed file. \
    By default, an internal QByteArray buffer is created for you when you create a QBuffer. You can access this buffer directly by calling buffer(). You can also use QBuffer with an existing QByteArray by calling setBuffer(), or by passing your array to QBuffer's constructor.
    You read and write from the QBuffer instance, not the QByteArray. The QByteArray is just the internal storage used by the QBuffer. QBuffer allows you to treat a QByteArray as if it was a file or other random access I/O device.

    So when you write to the QBuffer instance, that is when the readyRead signal is emitted. Your slot can then retrieve the QByteArray and read the new contents.

  3. #3
    Join Date
    May 2009
    Posts
    75
    Thanks
    5
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: when QBuffer emits readyRead signal?

    Quote Originally Posted by d_stranz View Post
    So when you write to the QBuffer instance, that is when the readyRead signal is emitted. Your slot can then retrieve the QByteArray and read the new contents.
    I tried a little example
    qt-buffer.tar.gz

    Qt Code:
    1. class Dialog : public QDialog
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. explicit Dialog(QWidget *parent = 0);
    7. ~Dialog();
    8.  
    9. private:
    10. Ui::Dialog *ui;
    11.  
    12. QBuffer *m_buffer;
    13. QByteArray *m_bytearray;
    14.  
    15. public slots:
    16. void onClick(void);
    17. void onDataReady(void);
    18. };
    19.  
    20.  
    21. Dialog::Dialog(QWidget *parent) :
    22. QDialog(parent),
    23. ui(new Ui::Dialog)
    24. {
    25. ui->setupUi(this);
    26.  
    27. m_bytearray = new QByteArray;
    28. m_buffer = new QBuffer(m_bytearray);
    29. m_buffer->open(QIODevice::ReadWrite);
    30.  
    31. connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(onClick()));
    32. connect(m_buffer, SIGNAL(readyRead()), this, SLOT(onDataReady()));
    33. }
    34.  
    35. Dialog::~Dialog()
    36. {
    37. delete m_buffer;
    38. delete m_bytearray;
    39. delete ui;
    40. }
    41.  
    42. void Dialog::onClick(void)
    43. {
    44. qDebug() << "write in buffer";
    45. m_buffer->write("hallo");
    46. }
    47.  
    48. void Dialog::onDataReady(void)
    49. {
    50. ba = m_buffer->readAll();
    51. qDebug() << "read" << ba.size() << "bytes";
    52. }
    To copy to clipboard, switch view to plain text mode 

    when write() is called the readyRead() actually emitted.
    But once in the onDataReady(), the call to readAll() returns an empty bytearray, though in m_bytearray is present the string "hallo".

    It seems that it is positioned to the end of the bytearray. I tried to modify:
    Qt Code:
    1. void Dialog::onClick(void)
    2. {
    3. qDebug() << "write in buffer";
    4. m_buffer->write("hallo");
    5. m_buffer->reset();
    6. }
    To copy to clipboard, switch view to plain text mode 
    This works, but the second time I click the button it read a string "hallohallo", the third I read "hallohallohallo", an so on...

    what is the proper way to read only bytes written in onClick()?

    best regards
    max

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: when QBuffer emits readyRead signal?

    You still misunderstand, I think.

    When you construct a QBuffer with a QByteArray as an argument, that QByteArray is the one that will be modified when you call QBuffer::write(). Calling QBuffer::readAll() returns the internal QByteArray, not the one you gave it as the constructor argument. So of course, the internal array is empty because you told QBuffer not to use it, but to use yours instead.

    So the code you wrote first will work if you simply replace this line:

    Qt Code:
    1. m_buffer = new QBuffer(m_bytearray);
    To copy to clipboard, switch view to plain text mode 

    with this line:

    Qt Code:
    1. m_buffer = new QBuffer();
    To copy to clipboard, switch view to plain text mode 

    When you call QBuffer::reset(), you are telling QBuffer to go back to using its internal buffer and ignore yours, which is why you get a copy of your string in that case. Each time you write, you append more data to the buffer (which is why you get multiple copies of the string).

  5. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: when QBuffer emits readyRead signal?

    Since you have two access points I guess you will have to maintain your two positions yourself.

    Compare that with QFile, which is also a QIODevice.
    If you append to it, then the position information (QIODevice::pos() is the end of the file. If you start a read there, you won't get any data (you are at the end of the file after all).

    So you need to remember your read and write positions, then seek to the correct one before you perform the I/O operation.

    Cheers,
    _

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: when QBuffer emits readyRead signal?

    It sounds like you want the buffer to contain only the most recently written bytes. I think in this case you need to do something like the following:

    Qt Code:
    1. QByteArray copy = mpBuffer->readAll();
    2. QByteArray & internal = mpBuffer->buffer();
    3. internal.clear();
    4. mpBuffer->seek( 0 ); // Maybe not required; QBuffer might check the array size before writing
    To copy to clipboard, switch view to plain text mode 

    This should result in an empty buffer without a readyRead() signal. As the docs say:

    QByteArray & QBuffer::buffer()

    Returns a reference to the QBuffer's internal buffer. You can use it to modify the QByteArray behind the QBuffer's back.

Similar Threads

  1. QProcess emits readyRead too late!
    By dynup in forum Qt Programming
    Replies: 6
    Last Post: 23rd March 2015, 17:42
  2. Replies: 4
    Last Post: 25th September 2014, 15:21
  3. Passing pointer to object that emits a signal
    By Gadgetman53 in forum Qt Programming
    Replies: 2
    Last Post: 17th April 2011, 21:04
  4. Replies: 3
    Last Post: 2nd April 2011, 13:13
  5. Replies: 4
    Last Post: 23rd January 2011, 10:08

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.