客戶端間通信功能預(yù)覽
信號(hào)關(guān)聯(lián)機(jī)制
整體的邏輯關(guān)系實(shí)現(xiàn)
//用戶上線顯示(包括自身和其他用戶)
connect(c,SIGNAL(getUserInfSuccess(int)),this,SLOT(displayUser(int)));
//好友密浑、黑名單亏娜、陌生人關(guān)系改變
connect(c,SIGNAL(changeRelation(ToolButton*,int,int)),this,SLOT(changeUserRelation(ToolButton*,int,int)));
//處理聊天消息 connect(c,SIGNAL(haveTalkMessage(int,QString)),this,SLOT(haveTalkMessage(int,QString)));
//用戶下線處理
connect(c,SIGNAL(userOffline(int)),this,SLOT(userOffline(int)));
//下線成功后界面處理
connect(c,SIGNAL(OfflineSuccess()),this,SLOT(OfflineSuccess()));
各部分具體實(shí)現(xiàn):
1薇溃、用戶信息顯示
新用戶上線后章喉,顯示他的信息
void ChatDlg::displayUser(int userid)
{
//為新用戶創(chuàng)建toolbutton和聊天室
Client* c = Common::getClientInstance();
RelationUser* user= c->getUserInfById(userid);
ToolButton* toolBtn = new ToolButton(userid);
_toolButtons[userid] = toolBtn;
ChatRoomDlg* chatRoom = new ChatRoomDlg(userid);
_rooms[userid] = chatRoom;
connect(toolBtn,SIGNAL(showChatRoom(int)),this,SLOT(showChatRoom(int)));
//設(shè)置顯示信息
QString iconPath = QString(":/Resources/registface/") + QString::number(user->face) + ".png";
toolBtn->setIcon(QIcon(iconPath));
toolBtn->setTextRows(QStringList() << user->display << user->sign);
if( FRIEND == user->relation )
{
_layoutFriend->addWidget(toolBtn);
}
else if( BLACK == user->relation )
{
_layoutBlack->addWidget(toolBtn);
}
else if( STRANGER == user->relation )
{
_layoutStranger->addWidget(toolBtn);
}
}
2搜锰、用戶關(guān)系改變
改變用戶之間的好友關(guān)系
void ChatDlg::changeUserRelation(ToolButton* relationUser,int oldRelation,int newRelation)
{
Q_UNUSED(oldRelation);
Client* c = Common::getClientInstance();
c->getUserInfById(relationUser->getUserid())->relation = newRelation;
if( FRIEND == newRelation )
{
_layoutFriend->addWidget(relationUser);
}
else if( BLACK == newRelation )
{
_layoutBlack->addWidget(relationUser);
}
else if( STRANGER == newRelation )
{
_layoutStranger->addWidget(relationUser);
}
}
3伴郁、通信消息處理
void ChatDlg::haveTalkMessage(int userid,QString talk)
{
_rooms[userid]->doTalkMessage( talk );
if(activeRoom != _rooms[userid] )
{
//為方便用戶讀取新消息,將有消息的toolbutton設(shè)置特殊stylesheet提醒用戶
_toolButtons[userid]->setStyleSheet("background-color: rgb(170, 255, 255);");
}
Client* c = Common::getClientInstance();
//將聊天消息表示在toolbutton上
_toolButtons[userid]->setTextRows(QStringList()<<c->getDisplay()<<c->getSign()<<talk);
}
4蛋叼、用戶下線處理
其他用用戶下線后的處理
void ChatDlg::userOffline(int userid)
{
//取得下線用戶的layou后焊傅,刪除
Client* c = Common::getClientInstance();
RelationUser* userInf = c->getUserInfById(userid);
QVBoxLayout* userLayout;
if( FRIEND == userInf->relation )
{
userLayout = _layoutFriend;
}
else if( BLACK == userInf->relation )
{
userLayout = _layoutBlack;
}
else if( STRANGER == userInf->relation )
{
userLayout = _layoutStranger;
}
userLayout->removeWidget(_toolButtons[userid]);
//清理結(jié)構(gòu)體
_toolButtons[userid]->close();
_toolButtons.remove(userid);
_rooms[userid]->close();
_rooms.remove(userid);
}
5、下線界面處理
用戶下線后除了關(guān)系消息處理外狈涮,界面也是需要處理的狐胎。
void ChatDlg::OfflineSuccess()
{
//offline成功后,關(guān)閉所有窗口
foreach(ChatRoomDlg* cr, _rooms)
{
cr->close();
}
close();
}
聊天類型消息區(qū)別
1歌馍、聊天消息格式
//表示聊天信息
void ChatRoomDlg::doTalkMessage(QString message)
{
ui->txtbro_msg->setTextColor(Qt::blue);
QFont font = ui->txtbro_msg->font();
font.setPointSize(12);
ui->txtbro_msg->setFont(font);
QString time = QDateTime::currentDateTime().toString("hh:mm:ss");
QString dispName = Common::getClientInstance()->getUserInfById( _userid )->display;
ui->txtbro_msg->append(time + tr(" [") + dispName + tr("] 對(duì)你說:"));
ui->txtbro_msg->append(message);
}
2握巢、消息發(fā)送
//發(fā)送消息,并表示在本聊天室中
void ChatRoomDlg::on_tb_sendMsg_clicked()
{
QString message = ui->txtEdt_msg->toHtml();
ui->txtbro_msg->setTextColor(Qt::blue);
QFont font = ui->txtbro_msg->font();
font.setPointSize(12);
ui->txtbro_msg->setFont(font);
QString time = QDateTime::currentDateTime().toString("hh:mm:ss");
QString dispName = Common::getClientInstance()->getUserInfById( _userid )->display;
ui->txtbro_msg->append(time + tr("你對(duì) [") + dispName + tr("] 說:"));
ui->txtbro_msg->append(message);
Client* c = Common::getClientInstance();
c->sendChatMessage(_userid,ui->txtEdt_msg->toPlainText());
ui->txtEdt_msg->clear();
ui->txtEdt_msg->setFocus();
}
3骆姐、聊天消息基本格式
//發(fā)送聊天信息
void Client::sendChatMessage(int receiverUserid,QString message)
{
QMap<QString,QString> msg;
msg["requestKind"]= QString::number(TALK);
msg["receiver"] = QString::number(receiverUserid);
msg["message"]= message;
_clientSocket->sendMessage(msg);
}
消息類型區(qū)分
//處理用戶消息
void Client::receiveMessage(QMap<QString,QString> message)
{
int requestKind = message["requestKind"].toInt();
//處理消息的代碼過多镜粤,才分成函數(shù)進(jìn)行調(diào)用
if( REGISTER_SUCCESS == requestKind)
{
//處理注冊(cè)成功消息
doRegisterSuccess(message);
}
else if(LOGIN_SUCCESS == requestKind )
{
//處理登陸成功消息
doLoginSuccess(message);
}
else if(LOGIN_NO_ACCOUNT == requestKind )
{
//處理登陸失敗消息
doLoginNoAccount(message);
}
else if(GET_USER_INF_SUCCESS == requestKind)
{
//處理取得其他用戶成功消息
doGetUserInfSuccess(message);
}
else if(USER_ONLINE == requestKind)
{
//處理其他用戶上線消息
doUserOnline(message);
}
else if(HAVE_TALK_MESSAGE == requestKind)
{
//處理其他用戶發(fā)送的消息
doHaveTalkMessage(message);
}
else if(USER_OFFLINE == requestKind)
{
//處理其他用戶下線消息
doUserOffline(message);
}
else if(OFFLINE_SUCCESS == requestKind)
{
//處理本用戶下線成功消息
doOfflineSuccess(message);
}
return ;
}
聊天基礎(chǔ)界面
運(yùn)行效果
服務(wù)器客戶端系統(tǒng)完整源碼
下載地址: