1、实现功能
本程序模拟实现QQ群聊功能,采用UDP通信方式,可以设置字体,保存聊天记录等,实时显示上线离开人数以及具体人员。可视为简化版的腾讯QQ。目前只有群聊,未实现一对一单独聊天。
完整源代码见:https://download.csdn.net/download/weixin_44618297/85076196
2、效果图
3、程序结构
4、部分程序源码
dialoglist.cpp
#include "dialoglist.h"
#include "ui_dialoglist.h"
#include <QToolButton>
#include "widget.h"
#include <QMessageBox>
dialoglist::dialoglist(QWidget *parent) :
QWidget(parent),
ui(new Ui::dialoglist)
{
ui->setupUi(this);
setWindowTitle("QQ2022");
setWindowIcon(QIcon(":/images/qq.png"));
QList<QString> namelist;
namelist<<"Cherry"<<"jj"<<"wy"<<"dr"<<"ymrl"<<"spqy"<<"lswh"<<"qmnn";
QVector<QToolButton*> vtoolbtn;
for(int i = 0; i<8; i++)
{
QToolButton *btn = new QToolButton;
QString str = QString(":/images/%1.png").arg(namelist.at(i));
btn->setText(namelist[i]);
btn->setIcon(QPixmap(str));
btn->setIconSize(QPixmap(str).size());
ui->vLayout->addWidget(btn);
vtoolbtn.push_back(btn);
isShow.push_back(false);
btn->setAutoRaise(true);
btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
}
for(int i = 0; i < vtoolbtn.size(); i++)
{
connect(vtoolbtn.at(i), &QToolButton::clicked, [=](){
if(isShow[i])
{
QString str = QString("%1 window already opened").arg(vtoolbtn[i]->text());
QMessageBox::warning(this, "warn", str);
return;
}
isShow[i] = true;
Widget * window = new Widget(0, vtoolbtn[i]->text());
window->setWindowTitle(vtoolbtn[i]->text());
window->setWindowIcon(vtoolbtn[i]->icon());
window->show();
connect(window, &Widget::closewidget, [=](){
isShow[i] = false;
});
});
}
}
dialoglist::~dialoglist()
{
delete ui;
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDataStream>
#include <QMessageBox>
#include <QDateTime>
#include <QDebug>
#include <QColorDialog>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
Widget::Widget(QWidget *parent, QString name)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
udpSocket = new QUdpSocket(this);
uName = name;
this->port = 1111;
udpSocket->bind(port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
connect(ui->sendbtn, &QPushButton::clicked, [=](){
sendMsg(Msg);
});
connect(udpSocket, &QUdpSocket::readyRead, this, &Widget::ReceiveMessage);
sendMsg(UsrEnter);
connect(ui->exitbtn, &QPushButton::clicked, this, &QWidget::close);
connect(ui->fontComboBox, &QFontComboBox::currentFontChanged, [=](const QFont &font){
ui->msgTextEdit->setCurrentFont(font);
ui->msgTextEdit->setFocus();
});
void (QComboBox:: *cbxsingal)(const QString &test) = &QComboBox::currentIndexChanged;
connect(ui->sizeComboBox, cbxsingal, [=](const QString &text){
ui->msgTextEdit->setFontPointSize(text.toDouble());
ui->msgTextEdit->setFocus();
});
ui->boldbtn->setCheckable(true);
connect(ui->boldbtn, &QToolButton::clicked, [=](bool ischeck){
if(ischeck)
{
ui->msgTextEdit->setFontWeight(QFont::Bold);
}
else
{
ui->msgTextEdit->setFontWeight(QFont::Normal);
}
});
ui->italicbtn->setCheckable(true);
connect(ui->italicbtn, &QToolButton::clicked, [=](bool ischeck){
ui->msgTextEdit->setFontItalic(ischeck);
});
ui->underline->setCheckable(true);
connect(ui->underline, &QToolButton::clicked, [=](bool ischeck){
ui->msgTextEdit->setFontUnderline(ischeck);
});
connect(ui->colorbtn, &QToolButton::clicked, [=](){
QColor color = QColorDialog::getColor(Qt::red);
ui->msgTextEdit->setTextColor(color);
});
connect(ui->clearbtn, &QToolButton::clicked, [=](){
ui->msgBrowser->clear();
});
connect(ui->savebtn, &QToolButton::clicked, [=](){
if(ui->msgBrowser->document()->isEmpty())
{
QMessageBox::warning(this,"warn","the text is empty!");
}
else
{
QString path = QFileDialog::getSaveFileName(this, "save record", "chat record", "(*.txt)");
QFile file(path);
file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream stream(&file);
stream << ui->msgBrowser->toPlainText();
file.close();
}
});
}
void Widget::ReceiveMessage()
{
qint64 size = udpSocket->pendingDatagramSize();
QByteArray array = QByteArray(size, 0);
udpSocket->readDatagram(array.data(), size);
QDataStream stream (&array, QIODevice::ReadOnly);
int msgtype;
stream >> msgtype;
QString usrname;
QString msg;
QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
switch(msgtype)
{
case Msg:
stream >> usrname >> msg;
ui->msgBrowser->setTextColor(Qt::blue);
ui->msgBrowser->append("[" + usrname + "]" + time);
ui->msgBrowser->append(msg);
break;
case UsrEnter:
stream >> usrname;
usrEnter(usrname);
break;
case UsrLeft:
stream >> usrname;
usrLeft(usrname, time);
break;
default:
break;
}
}
void Widget::sendMsg(MsgType type)
{
QByteArray array;
QDataStream stream(&array, QIODevice::WriteOnly);
stream << type << getUsr();
switch(type)
{
case Msg:
if(ui->msgTextEdit->toPlainText() == "")
{
QMessageBox::warning(this, "warn", "send msg is empty");
return;
}
stream << getMsg();
break;
case UsrEnter:
break;
case UsrLeft:
break;
default:
break;
}
udpSocket->writeDatagram(array, QHostAddress::Broadcast, port);
}
void Widget::usrEnter(QString usrname)
{
bool isempty = ui->usrtableWidget->findItems(usrname, Qt::MatchExactly).isEmpty();
if(isempty)
{
QTableWidgetItem * usr = new QTableWidgetItem(usrname);
ui->usrtableWidget->insertRow(0);
ui->usrtableWidget->setItem(0, 0, usr);
ui->msgBrowser->setTextColor(Qt::gray);
ui->msgBrowser->append(QString("%1 login").arg(usrname));
ui->usrNumlbl->setText(QString("online usr: %1").arg(ui->usrtableWidget->rowCount()));
sendMsg(UsrEnter);
}
}
void Widget::usrLeft(QString usrname, QString time)
{
bool isempty = ui->usrtableWidget->findItems(usrname, Qt::MatchExactly).isEmpty();
if(!isempty)
{
int row = ui->usrtableWidget->findItems(usrname, Qt::MatchExactly).first()->row();
ui->usrtableWidget->removeRow(row);
ui->msgBrowser->setTextColor(Qt::gray);
ui->msgBrowser->append(QString("%1 logout time:%2").arg(usrname).arg(time));
ui->usrNumlbl->setText(QString("online usr: %1").arg(ui->usrtableWidget->rowCount()));
}
}
QString Widget::getUsr()
{
return this->uName;
}
QString Widget::getMsg()
{
QString str = ui->msgTextEdit->toHtml();
ui->msgTextEdit->clear();
ui->msgTextEdit->setFocus();
return str;
}
void Widget::closeEvent(QCloseEvent *e)
{
emit this->closewidget();
sendMsg(UsrLeft);
udpSocket->close();
udpSocket->destroyed();
QWidget::closeEvent(e);
}
Widget::~Widget()
{
delete ui;
}
|