PDA

View Full Version : QSocketNotifier Qt 4.5 Windows



bunjee
18th April 2009, 13:06
Hey trolls,
Consider the following code:



socketNotifier = new QSocketNotifier(0, QSocketNotifier::Read, q);
socketNotifier->setEnabled(true);

QObject::connect(socketNotifier, SIGNAL(activated(int)), q, SLOT(onReadyRead()));

QFile file;
if (file.open(0, QFile::WriteOnly) == true)
{
QTextStream stream(&file);
stream << "lol";
file.close();
}


My onReadyRead() slot never gets called.

Why ?

bunjee
18th April 2009, 16:17
http://lists.trolltech.com/qt-interest/2006-07/thread01097-0.html


stdin on Windows is a magic little beast that tries to work both like a
windows handle, and as the Posix FILE* handle (e.g., fileno(stdin) returns
something that can be passed to other BSD emulation functions). The problem
is that it is not a pipe. It isn't a socket. It's not a file. It is a
special buffered device that is flushed on endline or EOF, and sometimes it
can get flushed by other activity.

You cannot use QSocketNotifier to receive notifications on stdin, because
Windows doesn't send single object notifications on it. QSocketNotifier on
Windows is designed to work with network sockets, and stdin isn't a socket
per se.

Andreas

bunjee
18th April 2009, 17:16
I'm now using a QTimer, but I get a freeze in my callback:


d->timer.stop();

QFile file;
file.open(stdin, QFile::ReadOnly);
if (file.isReadable())
{
file.readAll(); // Freezes the process
}

d->timer.start(100);

Any idea?

bunjee
18th April 2009, 22:17
Here is the solution:


#include "qkReceptor.h"

// Qt includes
#include <qsocketnotifier>
#include <qtextstream>
#include <qtimer>

//================================================== ===========================
// Private
//================================================== ===========================

#include "qkReceptor_p.h"

qkReceptorPrivate::qkReceptorPrivate(qkReceptor * p)
: qkPrivate(p)
{
}

void qkReceptorPrivate::init()
{
Q_Q(qkReceptor);

q->start();
}

//================================================== ===========================
// Ctor / dtor
//================================================== ===========================

qkReceptor::qkReceptor(QObject * parent)
: QThread(parent), qkPrivatable(new qkReceptorPrivate(this))
{
Q_D(qkReceptor);
d->init();
}

qkReceptor::~qkReceptor()
{
}

//================================================== ===========================
// Protected QThread reimplementation
//================================================== ===========================

void qkReceptor::run()
{
// A timer to avoid high CPU charge
QTimer timer;

connect(&timer, SIGNAL(timeout()), this, SLOT(onCheckStdin()), Qt::DirectConnection);

timer.start(100);

QThread::exec();
}

//================================================== ===========================
// Private slots
//================================================== ===========================

void qkReceptor::onCheckStdin()
{
QTextStream stream(stdin);

// Do we have a new line to be read ?
QString line = stream.readLine();

if (line != "")
{
// Do something with our line

qkPrint(line.C_STR);
}
}


If someone finds a proper way on windows, keep us posted.