Buenas compañeros .
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:
App.hpp
Client.hpp
Window.hpp:
App.cpp:
Client.cpp:
Window.cpp:
main.cpp:
Server.cpp:
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
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 (cpp) [Seleccionar]
#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 (cpp) [Seleccionar]
#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 (cpp) [Seleccionar]
#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 (cpp) [Seleccionar]
#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 (cpp) [Seleccionar]
#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 (cpp) [Seleccionar]
#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 (cpp) [Seleccionar]
#include "App.hpp"
int main(int argc,char *argv[])
{
QApplication Qt(argc,argv);
App *app = new App();
return Qt.exec();
}
Server.cpp:
Código (c++) [Seleccionar]
#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;
Selector.remove(Client[i].s);
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