巧妙使用QMap和QMultiMap实现QT使用UDP一对多聊天
最近开发了一个Super Helpdesk的项目, 在聊天模块,使用QMap储存发送过来的用户名和ip地址,利用QMultiMap存储送过来的消息,在有聊天的时候消息自动发送到all messages并存储在Qmultimap里面,当用户双击chat list的用户时候,自动调入相应用户的聊天信息,
和IP 地址,这样就实现了不切换界面来实现一对多聊天。如何分辨用户名字,在之前的帖子里面有说,可以参考一下,这个方案只是利用了mysql存储的IP地址,去掉了聊天服务器(上线即自动update IP地址到mysql服务器)。 谢谢各位网友分享的资料。具体程序请访问
www.pavogroup.top 下载。
void EngineerWindow::on_readyRead() { //是否还有待读取的传入数据报 while(m_udpSocket->hasPendingDatagrams()) { QByteArray data; //返回待读取的数据报的字节数 data.resize(m_udpSocket->pendingDatagramSize()); // QHostAddress peerAddr; // quint16 peerPort; //读取数据报的内容 m_udpSocket->readDatagram(data.data(),data.size(),&peerAddr,&peerPort); senderPeerAddress = peerAddr; QString str = data.data(); QStringList list = str.split("///"); senderName = list.at(list.length()-1); strReceiveWithoutName = list.at(list.length ()-2); // QString peer = "[From ] +"+peerAddr.toString()+":"+QString::number(peerPort)+"] "; sendTitle = "[From "+senderName+ "-" + QTime::currentTime ().toString () + "]: "; // ui->plainTextEdit_Chat_Messages->appendPlainText(peer+str); QTextCharFormat fmt; //字体色 strReceiveWithoutNameEmit = strReceiveWithoutName; senderNameEmit = senderName; senderPeerAddressEmit = senderPeerAddress; // QString messageForwardToChatForm = sendTitle + strReceiveWithoutName; //on_readyReadEmit(); if(ui->label_ChatWithName->text ().isEmpty () || ui->label_ChatWithName->text () == senderName) { ui->label_ChatWithName->setText (senderName); fmt.setForeground(QBrush(Qt::blue)); ui->plainTextEdit_Chat_Messages->mergeCurrentCharFormat(fmt); ui->plainTextEdit_Chat_Messages->appendPlainText(sendTitle+strReceiveWithoutName); dstIP = peerAddr.toString (); } if(senderName != senderNameTempForColor) { senderNameTempForColor = senderName; QTextCharFormat fmt; //字体色 fmt.setForeground(QBrush(QColor::fromHsl(rand()%360,rand()%256,rand()%200))); ui->plainTextEdit_Chat_Messages_All->mergeCurrentCharFormat(fmt); ui->plainTextEdit_Chat_Messages_All->appendPlainText(sendTitle+strReceiveWithoutName); } else { ui->plainTextEdit_Chat_Messages_All->appendPlainText(sendTitle+strReceiveWithoutName); } QTableWidgetItem *senderItem = new QTableWidgetItem; senderItem->setText(senderName); QTableWidgetItem *peerAddrItem = new QTableWidgetItem; peerAddrItem->setText(peerAddr.toString ()); ui->tableWidget_Engineer_ChatList->setRowCount(chatList.count ()+1); if(!chatList.contains (senderName)) { chatList.insert (senderName, peerAddr); ui->tableWidget_Engineer_ChatList->setItem (chatListRow, chatListCol1, senderItem); ui->tableWidget_Engineer_ChatList->setItem (chatListRow, chatListCol2, peerAddrItem); chatListRow++; } else { chatList.remove (senderName); QTest::qSleep (20); chatList.insert (senderName, peerAddr); if(!ui->tableWidget_Engineer_ChatList->size ().isEmpty ()) { for(int row = ui->tableWidget_Engineer_ChatList->rowCount()-1; row >=0; row--) { if(ui->tableWidget_Engineer_ChatList->item(row,0)==nullptr || ui->tableWidget_Engineer_ChatList->item(row,1)->text().isEmpty()) { } else { QString item1 = ui->tableWidget_Engineer_ChatList->item(row,0)->text (); QString item2 = ui->tableWidget_Engineer_ChatList->item(row,1)->text (); if(item1 == senderName && item2 != peerAddr.toString ()) { ui->tableWidget_Engineer_ChatList->setItem (row, chatListCol1, senderItem); ui->tableWidget_Engineer_ChatList->setItem (row, chatListCol2, peerAddrItem); // chatListRow++; } } } } } chatMessages.insertMulti (senderName, sendTitle+strReceiveWithoutName); delete senderItem; delete peerAddrItem; } } void EngineerWindow::on_pushButton_Chat_SendMessage_clicked() { if(ui->plainTextEdit_Send_Messages->document ()->isEmpty ()) { QMessageBox::warning (this, "Remind", "You could not send empty message out!"); return; } if(ui->label_ChatWithName->text ()== "") { QMessageBox::information (this, "Remind","Pls double click on the contact list to choose who are you want to talk first."); return; } QString chatWithName = ui->label_ChatWithName->text (); QHostAddress dstAddr(dstIP); //目标端口 quint16 dstPort = 8686; //= ui->lineEdit_SendTo_Port->text().toInt (); QString msg = ui->plainTextEdit_Send_Messages->toPlainText () + "///" + WindowsUserName; QByteArray str = msg.toUtf8(); //发出数据报 m_udpSocket->writeDatagram(str,dstAddr,dstPort); QTextCharFormat fmt; //字体色 fmt.setForeground(QBrush(Qt::darkRed)); QString msgLocal = ui->plainTextEdit_Send_Messages->toPlainText (); ui->plainTextEdit_Chat_Messages->mergeCurrentCharFormat(fmt); ui->plainTextEdit_Chat_Messages->appendPlainText("[To " + chatWithName + "-" + QTime::currentTime ().toString () + "]: "+msgLocal); chatMessages.insertMulti (chatWithName, "[To " + chatWithName + "-" + QTime::currentTime ().toString () + "]: "+msgLocal); ui->plainTextEdit_Send_Messages->clear (); }