PDA

View Full Version : QBuffer bytesWritten() problem



QAlex
28th September 2009, 16:47
Hi all,
I spent some time trying to see the signal bytesWritten working over a QBuffer instance, but without any succes... I post here a little example of my code.



QBuffer buffer;
char ch;

connect(&buffer,SIGNAL(bytesWritten(qint64)),this,SLOT(test (qint64)));

buffer.open(QBuffer::ReadWrite);
buffer.write("Qt rocks!");
buffer.seek(0);
buffer.getChar(&ch); // ch == 'Q'
qDebug("%c",ch);
buffer.getChar(&ch); // ch == 't'
qDebug("%c",ch);
buffer.getChar(&ch); // ch == ' '
qDebug("%c",ch);
buffer.getChar(&ch); // ch == 'r'
qDebug("%c",ch);


this is the test SLOT:



void classname::test()
{
qDebug("test test test");
}


The code compile without any problem, but the signal bytesWritten is always absent!!!
I hope someone can help me, because I'm stuck on this annoying problem. :mad:

In my opinion could be a Qt bug, but since I'm a novice in Qt4 programming, I like to discuss with someone expert (or guru... :p) before thinking bad things!!!

A possible workaround is to define a new QIODevice subclass in which I have to reimplement the bytesWritten signal in order to create a new QBuffer working subclass!
But I hope to make the original one working!

Best regards,
Alessandro

wysota
28th September 2009, 19:10
It's not nice to say "hey, something doesn't work in my code, I think it's a Qt bug". Qt is open source, read the source of QBuffer write and see when the signal gets emitted.

QAlex
29th September 2009, 09:43
Thanks for the reply!
I apologize for my presumption... you are right!
But I told so, since a friend of mine has the same problem.
We found yesterday a possible workaround of this problem... It seems that connecting the two signals bytesWritten and readyRead, the signal bytesWritten is emitted:



socket = new QBuffer(&pckBuffer,this);
connect(socket,SIGNAL(bytesWritten(qint64)),pCl,SL OT(SendPck(qint64)));
connect(socket,SIGNAL(readyRead()),this,SLOT(dummy ()));


where dummy can be also a slot that does nothing, just like this:



void classname::dummy()
{
}


With this configuration, the code works for me and also for my friend.
We don't know exactly why, but the code really works!!! Maybe we will check the reason in the Qt source, as suggested by you! ;)

Best Regards,
Alessandro

wysota
29th September 2009, 10:05
I somehow doubt connecting a slot to another signal will start making this signal work.

If you had looked into Qt's source code you would have noticed a construction like this:

#ifndef QT_NO_QOBJECT
d->writtenSinceLastEmit += len;
if (d->signalConnectionCount && !d->signalsEmitted && !signalsBlocked()) {
d->signalsEmitted = true;
QMetaObject::invokeMethod(this, "_q_emitSignals", Qt::QueuedConnection);
}
#endif

From this it's obvious you need to return to the event loop for the signal to be emitted. Other signals and slots have nothing to do with this. Also if you took a look at _q_emitSignals() you'd notice that bytesWritten() and readyRead() are always emitted together regardless of actual read and write operations (which makes sense because if you write something to the buffer it can be read back from the buffer immediately). Now inspect your code and determine what is going on there instead of using silly workarounds.