PDA

View Full Version : QCoreApplication, QTcpSocket and Console input question



QPlace
20th July 2007, 16:03
I have following test code:

int main(int argc, char *argv[])
{

QCoreApplication a(argc, argv);
ClientSocket client(&a);
client.connectToHost(QHostAddress::LocalHost, (quint16)12000,QTcpSocket::ReadWrite);

/* offensive part
QTextStream stream(stdin);
QString line;
do {
line = stream.readLine();
if (!line.isNull())
client.SendCommand(1, line);

} while (!line.isNull());
*/
return a.exec();


}

ClientSocket is derived from QTcpSocket. When "offensive part" is commented out everything works fine, i.e socket connects to the server etc. When "offensive part" is uncommented the main event loop is not started, QT event system is broken.

My question is: how to enable input from the console and also have socket signals processed correctly? I want to be able to do something similar to telnet, where the user types in the console and text is written to a socket for transmission. I understand that I can put socket in the separate thread, but I wonder if I miss some class (or functionality in classes that I use) that will allow me to do it in the main thread.

jacek
20th July 2007, 17:09
My question is: how to enable input from the console and also have socket signals processed correctly?
Create an object, connect it to readyRead() signal of the device on which QTextStream operates and let it read the input.

QPlace
21st July 2007, 02:53
Create an object, connect it to readyRead() signal of the device on which QTextStream operates and let it read the input.

I am new to QT and I am sure that I am missing something. Nevertheless, I tried to implement your advise and in doing so I stumbled upon another problem. I created ConsoleInput class:

class ConsoleInput : public QObject
{

Q_OBJECT

QTextStream ts;
public:
ConsoleInput(QObject *parent) : ts(stdin), QObject(parent)
{
connect (ts.device(), SIGNAL (readyRead()), this, SLOT(lineIsReady()));
};
~ConsoleInput() {};

private slots:
void lineIsReady()
{
QString line = ts.readLine();
};};

my main.cpp is:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ConsoleInput cn(&a);
return a.exec();
};

Now I cannot get an input from the console. What am I doing wrong?

jacek
24th July 2007, 02:06
It seems that QFile doesn't emit any signals, although QIODevice docs suggest it should. I've tried to make it work with QSocketNotifier, but it didn't work well.

You can make it work by implementing some loop that will check whether there is no data to be read and run QCoreApplication::processEvents() (remember to use non-blocking operations on the file) or using QTimer to check for new characters periodically.

QPlace
24th July 2007, 02:42
Thank you for looking into this.
I gave up on the attempts to do it with one event loop from CoreApplication it and did it with two threads - one for console input and another for socket comms.:)

jacek
24th July 2007, 17:35
I gave up on the attempts to do it with one event loop from CoreApplication it and did it with two threads
Well, that's the easiest solution, but one thread should be enough. I really don't know why QSocketNotifier doesn't work, but unfortunately I don't have time to look into it now.