承接上篇登錄模塊,本文講解基於 Qt + UDP 的好友列表面板、雙擊打開聊天窗口、消息收發顯示的核心實現。界面採用無邊框透明風格,通信協議自定義二進制流 (QDataStream)。
void Panel::init() {
udpSocket = new QUdpSocket(this);
udpSocket->bind(6666); // 綁定本地端口接收消息
// 上線通知:MSG_CLIENT_NEW_CONN
QString msgType = "MSG_CLIENT_NEW_CONN";
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_6);
out << (quint16)0 << msgType << usrname; // 佔位長度、類型、用戶名
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16)); // 回填長度
udpSocket->writeDatagram(block, QHostAddress(serverIp), serverPort+1);
connect(udpSocket, &QUdpSocket::readyRead, this, &Panel::recvMsg);
}
void Panel::on_itemDoubleClicked(QListWidgetItem *item) {
QString name = item->text().replace("\n", "");
ChatForm *chat = chatHash.value(name);
if (!chat) {
chat = new ChatForm(usrname, serverIp, serverPort, udpSocket);
chat->setWindowTitle("chatting with " + name);
chatHash.insert(name, chat); // 緩存窗口,避免重複創建
}
chat->setWindowFlags(Qt::FramelessWindowHint);
chat->setAttribute(Qt::WA_TranslucentBackground);
chat->show();
}
void ChatForm::displayText(QString nickname, QString usrname, QString text) {
QListWidgetItem *item = new QListWidgetItem(
nickname + "(" + usrname + ") :\n" + text + "\n");
ui->listWidget->addItem(item);
}
void ChatForm::on_sendButton() {
QString text = ui->textEdit->toPlainText();
if (text.isEmpty()) return;
// 解析窗口標題獲取目標用戶名
QString title = windowTitle().replace("].", "");
QString toId = title.split("[").at(1);
QString msgType = "MSG_CLIENT_CHAT";
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_6);
out << (quint16)0 << msgType << usrname << toId << text;
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16)); // 回填包長
udpSocket->writeDatagram(block, QHostAddress(serverIp), serverPort+1);
// 本地回顯
ui->listWidget->addItem("I say :\n" + text + "\n");
ui->textEdit->clear();
}

[quint16 包總長度] [QString 消息類型] [QString 發送者] [QString 接收者] [QString 內容] ...
seek(0) 回填。QDataStream 序列化 (長度前綴 + UTF-16 數據)。bind() 固定端口接收。FramelessWindowHint + WA_TranslucentBackground 實現自定義 UI。下一篇將講解服務端監聽、數據庫存儲、廣播消息等後台邏輯。