Xeracker y yo llevamos un par de días codeando un chat funcional y así de paso aprender un poco de interfaces en C++, el resultado creo que ha sido bastante bueno y a pesar de que aún tiene algunos bugs y falta la implementación de algunas funciones del mismo, está en condiciones de publicarse su code por si algún usuario quiere ayudar o dar opiniones y hacer críticas.
Scan:
De momento falta la función de mostrar los usuarios en el ListBox derecho, de imprimir los emoticonos en el campo de texto entre muchas otras que iremos añadiendo
A continuación os dejo el source de todos los archivos:
Headers
App.hpp
Código
#include "Window.hpp" #include "Client.hpp" class App { Window window; Client client; void Thread(); sf::Thread thread; public: App() : thread(&App::Thread, this), window("Anonimo") { thread.launch(); } };
Client.hpp
Código
#include <SFML/Network.hpp> class Client { sf::IpAddress ServerAddress; sf::TcpSocket Socket; sf::Packet Packet; void Receiver(); void Status(); void Sender(); bool connected; bool updated; public: Client(); sf::Thread R, S; sf::Packet Receive(); void Send(sf::Packet); bool IsConnected(); bool IsUpToDate(); };
Window.hpp:
Código
#include <QObject> #include <QtGui> #include <QFile> class Window : public QObject { Q_OBJECT public: Window(QString usu); ~Window(); void Iconos(); void Write(QString, QString); void ModificarEstado(bool estado); bool IsTextUpToDate() { return TextUpdated; } bool IsNickUpToDate() { return NickUpdated; } QString GetText(), GetNick(); private slots: void Send(); void logueoUsuario(); void configUser(); void escribirWink(); void escribirHappy(); void escribirHeart(); void escribirLaughter(); void escribirSad(); void escribirUuh(); void escribirWhoa(); private: /* Constructores De Ventana*/ QLineEdit *TextEdit; QLineEdit *UserEdit; QPushButton *SendButton; QPushButton *LogButton; QPushButton *CLogButton; QTextEdit *TextBox; QListWidget *UserBox; QVBoxLayout *mainLayout; QVBoxLayout *chatLayout; QVBoxLayout *usersLayout; QHBoxLayout *buttonLayout; QHBoxLayout *usutextLayout; QHBoxLayout *emoLayout; QWidget *window; QString usuario, estado; QLabel *etiqueta; QLabel *imagenChat; QLabel *imagenConectados; /*Emoticonos y Capa Emoticonos*/ QPushButton *emoWink, *emoHappy, *emoHeart, *emoLaughter, *emoSad, *emoUuh, *emoWhoa; bool TextUpdated, NickUpdated; };
Sources
App.cpp:
Código
#include "App.hpp" void App::Thread() { while(1) { if(!client.IsUpToDate()) { QString t1, t2; sf::String s1, s2; client.Receive() >> s1 >> s2; t1 = s1.toAnsiString().c_str(); t2 = s2.toAnsiString().c_str(); window.Write(t1,t2); } if(!window.IsTextUpToDate()) { sf::String str=window.GetText().toStdWString(); sf::Packet Pack; Pack << 1 << str; client.Send(Pack); Pack.clear(); } if(!window.IsNickUpToDate()) { sf::String str=window.GetNick().toStdWString(); sf::Packet Pack; Pack << 0 << str; client.Send(Pack); Pack.clear(); } if(client.IsConnected()) { window.ModificarEstado(true); } } }
Client.cpp:
Código
#include "Client.hpp" Client::Client() : R(&Client::Receiver, this), S(&Client::Sender, this), updated(true) { Socket.connect("**************", 25569); R.launch(); S.launch(); } void Client::Receiver() //Receiver Thread { while(1) { sf::Packet buffer; Socket.receive(buffer); Packet = buffer; buffer.clear(); updated=false; } } void Client::Sender() //Sender Thread { } sf::Packet Client::Receive() { updated=true; return Packet; } void Client::Send(sf::Packet Pack) { connected = (Socket.send(Pack) == sf::Socket::Done); } bool Client::IsUpToDate() { return updated; } bool Client::IsConnected() { return connected; }
Window.cpp:
Código
#include "Window.hpp" void Window::ModificarEstado(bool status) { if(status) estado = "Conectado"; else estado = "Desconectado"; window->setWindowTitle("Nick: "+usuario+" <---> Estado: "+estado); } void Window::escribirWink() { TextEdit->insert(QString(" ;) ")); } void Window::escribirHappy() { TextEdit->insert(QString(" :) ")); } void Window::escribirHeart() { TextEdit->insert(QString(" (L) ")); } void Window::escribirLaughter() { TextEdit->insert(QString(" :D ")); } void Window::escribirSad() { TextEdit->insert(QString(" :( ")); } void Window::escribirUuh() { TextEdit->insert(QString(" ¬¬ ")); } void Window::escribirWhoa() { TextEdit->insert(QString(" :O ")); } void Window::Iconos() { /* Emoticonos */ emoWink = new QPushButton; emoHappy = new QPushButton; emoHeart = new QPushButton; emoLaughter = new QPushButton; emoSad = new QPushButton; emoUuh = new QPushButton; emoWhoa = new QPushButton; QObject::connect(emoWink,SIGNAL(clicked()),this,SLOT(escribirWink())); QObject::connect(emoHappy,SIGNAL(clicked()),this,SLOT(escribirHappy())); QObject::connect(emoHeart,SIGNAL(clicked()),this,SLOT(escribirHeart())); QObject::connect(emoLaughter,SIGNAL(clicked()),this,SLOT(escribirLaughter())); QObject::connect(emoSad,SIGNAL(clicked()),this,SLOT(escribirSad())); QObject::connect(emoUuh,SIGNAL(clicked()),this,SLOT(escribirUuh())); QObject::connect(emoWhoa,SIGNAL(clicked()),this,SLOT(escribirWhoa())); emoWink->setIcon(QIcon("emoticonos/guinyo.png")); emoHappy->setIcon(QIcon("emoticonos/happy.png")); emoHeart->setIcon(QIcon("emoticonos/heart.png")); emoLaughter->setIcon(QIcon("emoticonos/laughter.png")); emoSad->setIcon(QIcon("emoticonos/sad.png")); emoUuh->setIcon(QIcon("emoticonos/uhh.png")); emoWhoa->setIcon(QIcon("emoticonos/whoa.png")); /* Capa Horizontal Emoticonos */ emoLayout = new QHBoxLayout; emoLayout->addWidget(emoWink); emoLayout->addWidget(emoHappy); emoLayout->addWidget(emoHeart); emoLayout->addWidget(emoLaughter); emoLayout->addWidget(emoSad); emoLayout->addWidget(emoUuh); emoLayout->addWidget(emoWhoa); /* Anidacion capa horizontal en vertical */ mainLayout->addLayout(emoLayout); } void Window::configUser() { usuario = UserEdit->text(); NickUpdated=false; delete etiqueta; delete UserEdit; delete CLogButton; window->setWindowTitle("Nick: "+usuario+" <---> Estado: "+estado); SendButton = new QPushButton("Enviar"); TextEdit = new QLineEdit; SendButton->setIcon(QIcon("emoticonos/aceptar.png")); QObject::connect(SendButton,SIGNAL(clicked()),this,SLOT(Send())); mainLayout->addWidget(TextEdit); mainLayout->addWidget(SendButton); window->setLayout(mainLayout); window->show(); } void Window::Write(QString user, QString msg) { TextBox->append(user+": "+msg); } void Window::Send() { if(TextEdit->text()!= "") { TextUpdated=false; TextEdit->clear(); } } QString Window::GetText() { TextUpdated=true; return TextEdit->text(); } QString Window::GetNick() { NickUpdated=true; return usuario; } void Window::logueoUsuario() { delete LogButton; delete SendButton; delete TextEdit; CLogButton = new QPushButton("Aceptar"); CLogButton->setIcon(QIcon("emoticonos/aceptar.png")); QObject::connect(CLogButton,SIGNAL(clicked()),this,SLOT(configUser())); UserEdit = new QLineEdit; etiqueta = new QLabel("Inserta nickname"); etiqueta->setAlignment(Qt::AlignCenter); mainLayout->addWidget(etiqueta); mainLayout->addWidget(UserEdit); mainLayout->addWidget(CLogButton); window->setLayout(mainLayout); window->show(); } Window::Window(QString user) : usuario(user), TextUpdated(true), NickUpdated(false) { window = new QWidget; LogButton = new QPushButton("Loguear"); LogButton->setIcon(QIcon("emoticonos/llave.png")); QObject::connect(LogButton,SIGNAL(clicked()),this,SLOT(logueoUsuario())); TextBox = new QTextEdit; TextBox->setReadOnly(true); TextBox->setMinimumSize(QSize(550,0)); UserBox = new QListWidget; imagenChat = new QLabel("Chat"); QImage imageChat("emoticonos/chat.png"); imagenChat->setPixmap(QPixmap::fromImage(imageChat)); imagenChat->setAlignment(Qt::AlignCenter); QLabel *etiquetaChat = new QLabel("Chat"); etiquetaChat->setAlignment(Qt::AlignCenter); imagenConectados = new QLabel("Conectados"); QImage imageUsers("emoticonos/conectados.png"); imagenConectados->setPixmap(QPixmap::fromImage(imageUsers)); imagenConectados->setAlignment(Qt::AlignCenter); QLabel *etiquetaConectados = new QLabel("Usuarios Conectados"); etiquetaConectados->setAlignment(Qt::AlignCenter); usutextLayout = new QHBoxLayout; TextEdit = new QLineEdit; SendButton = new QPushButton("Enviar"); SendButton->setIcon(QIcon("emoticonos/aceptar.png")); chatLayout = new QVBoxLayout; usersLayout = new QVBoxLayout; mainLayout = new QVBoxLayout; buttonLayout = new QHBoxLayout; window->setMinimumSize(700,500); window->setMaximumSize(700,500); QObject::connect(SendButton,SIGNAL(clicked()),this,SLOT(Send())); chatLayout->addWidget(imagenChat); chatLayout->addWidget(etiquetaChat); chatLayout->addWidget(TextBox); usersLayout->addWidget(imagenConectados); usersLayout->addWidget(etiquetaConectados); usersLayout->addWidget(UserBox); usutextLayout->addLayout(chatLayout); usutextLayout->addLayout(usersLayout); mainLayout->addLayout(usutextLayout); Iconos(); mainLayout->addWidget(TextEdit); buttonLayout->addWidget(SendButton); buttonLayout->addWidget(LogButton); mainLayout->addLayout(buttonLayout); window->setLayout(mainLayout); window->show(); } Window::~Window() {}
main.cpp:
Código
#include "App.hpp" int main(int argc,char *argv[]) { QApplication Qt(argc,argv); App *app = new App(); return Qt.exec(); }
Server.cpp:
Código
#include <SFML/Network.hpp> #include <iostream> using namespace std; struct Client{ sf::TcpSocket s; bool connected; sf::String alias; } Client[256]; int main(int argc, char *argv[]) { sf::TcpListener Server; sf::SocketSelector Selector; int Port = 25569; for(int i=0; i<256; i++) Client[i].connected=false, Client[i].alias="Unknown"; Server.listen(Port); cout << "Escuchando puerto " << Port << " TCP..." << endl; Selector.add(Server); while (Selector.wait()) { if (Selector.isReady(Server)) { for(int i=0; i<256; i++) { if(!Client[i].connected) { sf::Packet Packet; Server.accept(Client[i].s); cout << "Client connected (ID: " << i << ", IP: " << Client[i].s.getRemoteAddress() << ")" << endl; Selector.add(Client[i].s); Client[i].connected=true; break; } } } else { for(int i=0; i<256; i++) { if(Selector.isReady(Client[i].s)) { sf::Packet Packet; if(Client[i].s.receive(Packet) == sf::Socket::Done) { int com; Packet >> com; switch (com) { case 0: Client[i].alias.clear(); Packet >> Client[i].alias; cout << "Client " << i << " ha cambiado su alias a \"" << Client[i].alias.toAnsiString() << "\"." << endl; break; case 1: sf::String Msg; Packet >> Msg; cout << Client[i].alias.toAnsiString() << ": " << Msg.toAnsiString() << endl; Packet.clear(); Packet << Client[i].alias << Msg; for (int i=0; i<256; i++) if(Client[i].connected) Client[i].s.send(Packet); } break; } else { cerr << Client[i].alias.toAnsiString() << " se ha desconectado (ID: " << i << ", IP: " << Client[i].s.getRemoteAddress() << ")" << endl; Client[i].connected=false; Client[i].alias="Unknown"; break; } } } } } }
Con todo el code ya publicado, pongo link con un .rar que contiene lo archivos necesarios para compilar desde CodeBlocks junto con los emoticonos y las imágenes del programa.
http://www.mediafire.com/?9h7mlte60p6h2qd
Aclaro que se necesita tener instaladas la librerías Qt y SFML, si tenéis algún problema con su instalación subiré el .rar con las .dll de las librerias necesarias para el correcto funcionamiento del chat.
Un saludo a todos y esperamos que os guste