PDA

View Full Version : clean solution?



Dumbledore
29th October 2007, 00:15
For a chat program, when I receive some text from a peer, how do I display this in my QTextBrowser?

I know about QTextBrowser::append(), but what I mean is: how do I get my socket instance to know about my QTextBrowser instance?

I could pass the pointer to QTextBrowser to QServer's constructor then to QSocket's constructor so that in my receiveText() slot I can use QTextBrowser::append() to output the text I receive... but is there a cleaner solution?

wysota
29th October 2007, 08:36
You can subclass a socket and make it emit a signal with the message you want to append to the browser. Then you can connect the socket and the browser from within a component which knows them both.

Dumbledore
29th October 2007, 22:32
I see what you are saying, and I have already subclassed tcpSocket, but I don't see an easy way to connect the signal to the appropriate slot.

The code is really simple, its just split into many files.

MSocket.cpp


#include "MSocket.h"

void MSocket::recv() {
QTextStream in(this);
QString inChat;
inChat = in.readLine();
//chatOutput->append(inChat); <- this can't work.
}


MServer.cpp


#include "MServer.h"

MServer::MServer(QObject* parent) : QTcpServer(parent) {
}

void MServer::incomingConnection(int socketDescriptor) {
MSocket* socket = new MSocket(this);
socket->setSocketDescriptor(socketDescriptor);
}


MChat.cpp


#include "MChat.h"
#include <QMessageBox>


MChat::MChat(QMainWindow *parent) : QMainWindow(parent), tcpServer(NULL) {
setupUi(this);

//connections
connect(inputChat, SIGNAL(pressedReturn()),
sendButton, SLOT(animateClick()));

}

void MChat::on_actionConnect_activated() {
if (NULL == tcpServer) {
tcpServer = new MServer(this);
connect(tcpServer, SIGNAL(inText(QString&)), this,
SLOT(outputText(QString&)));
if (!tcpServer->listen(QHostAddress::Any, 43545)) {
QMessageBox::critical(this, tr("MChat"),
tr("Unable to start the server: %1.")
.arg(tcpServer->errorString()));
close();
return;
}

}
}

}

Dumbledore
29th October 2007, 22:59
So my solution is to first emit a signal with MSocket:


emit incomingChat(text);

Catch it with a slot from MServer, and emit it again to MChat:


slot relayText(text) {
emit text(text);
}

Catch it in MChat with a slot:


MChat:: outputText(QString& text) {
chatOutput->append(text);
}

There must be a cleaner way though.

jacek
29th October 2007, 23:26
You can connect a signal to a signal.

Dumbledore
30th October 2007, 00:44
alright, that makes it a little nicer.