QT

您所在的位置:网站首页 飞秋接收不到消息 QT

QT

2023-11-04 02:33| 来源: 网络整理| 查看: 265

Qt实现局域网聊天软件 1.简介1)基本功能2)添加功能3)效果 2.构建3.基本功能框架1)界面构建2)聊天功能实现3)文件传输功能4)其他功能 4.相关源码wdiget.hwidget.cpp 5.下载地址

1.简介 1)基本功能

本次设计参考了《Qt及Qt Quick开发实战精解》一书,并对其进行bug补全修正,添加些许新功能进行二次开发,基本的功能:

使用UDP进行组网聊天使用TCP进行文件传输能够更改字体,字体大小,粗体,斜体,下划线和字体颜色能保存聊天记录,清空聊天记录等能在同一个局域网下通过不同的ip地址加入组网 2)添加功能

添加功能如下:

修改中文乱码问题自Qt4转移至Qt5环境添加重绘事件设置窗口背景支持Enter键发送 消息对tablewidget进行优化布局其他功能修正添加 3)效果

在这里插入图片描述

我这里并没有对其进行多ip组网聊天测试,但是功能正常,清空聊天记录和保存功能也可以正常显示,这里就不再过多的赘述。

2.构建

此局域网聊天工具既要作为服务器端,又要作为客户端,因此以可将其作为端到端的P2P模式。 在这里插入图片描述

3.基本功能框架 构建基本界面 – 设计是模式下构建实现聊天功能 – 使用UDP来事项用户信息的显示和基本的聊天功能实现文件传输功能 – 使用TCP实现快速传输完善其他功能 – 类QQ聊i天(更改字体,保存聊天记录等 ) 1)界面构建

界面的话,需要三个界面来实现所有的功能,一个主窗口界面,一个文件发送端,一个文件接收端。构建如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eSbkW2EO-1584417405286)(Qt%E5%AE%9E%E7%8E%B0%E8%81%8A%E5%A4%A9%E5%B7%A5%E5%85%B7.assets/%E4%B8%BB%E7%95%8C%E9%9D%A2.png)]

在这里插入图片描述

在这里插入图片描述

2)聊天功能实现

UDP有个最显著的特点就是有着强大的广播功能,聊天功能就使用UDP协议,构建组网,在同一局域网下通信,这里只需要将程序运行在不同的ip环境下即可。

3)文件传输功能

使用TCP协议实现文件的快速传输,用TCP协议在Qt中的三次握手应用,调用界面,实现传输功能

在这里插入图片描述

在这里插入图片描述 在这里插入图片描述

4)其他功能

其他功能就是对字体的操作了,可以更改字体的颜色和大小,粗细,格式等等,通过调用Qt中font类的字体设置。

在这里插入图片描述 在这里插入图片描述

4.相关源码 wdiget.h #ifndef WIDGET_H #define WIDGET_H #include #include #include #include class QUdpSocket; class TcpServer; namespace Ui { class Widget; } // 枚举变量标志信息的类型,分别为消息,新用户加入,用户退出,文件名,拒绝接受文件 enum MessageType{Message, NewParticipant, ParticipantLeft, FileName, Refuse}; class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); void init(); //初始化背景色 protected: void newParticipant(QString userName, QString localHostName, QString ipAddress); //处理新用户加入 void participantLeft(QString userName, QString localHostName, QString time); //处理用户离开 void sendMessage(MessageType type, QString serverAddress=""); //使用UDP广播发送信息s QString getIP(); //获取ip地址 QString getUserName(); //获取用户名 QString getMessage(); //获得要发送的消息 void hasPendingFile(QString userName, QString serverAddress, QString clientAddress, QString fileName); //处理是否接收文件 bool saveFile(const QString& fileName); //保存聊天记录 void closeEvent(QCloseEvent *); //关闭事件 void paintEvent(QPaintEvent *event); //重绘事件 bool eventFilter(QObject *target, QEvent *event); //事件过滤器 private: Ui::Widget *ui; QUdpSocket *udpSocket; qint16 port; //定义端口 QString fileName; TcpServer *server; //声明TCP文件传输 QColor color; //定义字体颜色 QTextCodec * unCodec = QTextCodec::codecForName ( "GBK" ); // 用于解码 private slots: void processPendingDatagrams(); void on_sendButton_clicked(); void getFileName(QString); void on_sendToolBtn_clicked(); void on_fontComboBox_currentFontChanged(QFont f); void on_sizeComboBox_currentIndexChanged(QString ); void on_boldToolBtn_clicked(bool checked); void on_italicToolBtn_clicked(bool checked); void on_underlineToolBtn_clicked(bool checked); void on_colorToolBtn_clicked(); void currentFormatChanged(const QTextCharFormat &format); void on_saveToolBtn_clicked(); void on_clearToolBtn_clicked(); void on_exitButton_clicked(); }; #endif // WIDGET_H widget.cpp #include "widget.h" #include "ui_widget.h" #include #include #include #include #include #include #include #include "tcpserver.h" #include "tcpclient.h" #include #include #include #include #include Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); udpSocket = new QUdpSocket(this); port = 45454; udpSocket->bind(port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams())); sendMessage(NewParticipant); server = new TcpServer(this); connect(server, SIGNAL(sendFileName(QString)), this, SLOT(getFileName(QString))); connect(ui->messageTextEdit, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this, SLOT(currentFormatChanged(const QTextCharFormat))); init(); //初始化背景 } Widget::~Widget() { delete ui; } // 初始化背景 void Widget::init() { ui->messageBrowser->setStyleSheet("background-color:transparent;"); ui->messageTextEdit->setStyleSheet("background-color:transparent;"); ui->userTableWidget->setStyleSheet("background-color:transparent;"); ui->userTableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background-color:transparent;font:13pt '宋体';color: white;}"); //row ui->userTableWidget->verticalHeader()->setVisible(false); //ui->userTableWidget->verticalHeader()->setStyleSheet("QHeaderView::section{background-color:transparent;}"); //col //ui->userTableWidget->setStyleSheet("QTableCornerButton::section{background-color:transparent;}"); //左上角交会处 //设置键盘事件 ui->sendButton->setFocus(); ui->sendButton->setDefault(true); ui->messageTextEdit->installEventFilter(this);//设置完后自动调用其eventFilter函数 } // 使用UDP广播发送信息 void Widget::sendMessage(MessageType type, QString serverAddress) { QByteArray data; QDataStream out(&data, QIODevice::WriteOnly); QString localHostName = QHostInfo::localHostName(); QString address = getIP(); out toUnicode("警告"),unCodec->toUnicode("输入内容不能为空!"),QMessageBox::Ok); return; } out verticalScrollBar() ->setValue(ui->messageBrowser->verticalScrollBar()->maximum()); break; case NewParticipant : out userTableWidget->currentRow(); QString clientAddress = ui->userTableWidget->item(row, 2)->text(); out readDatagram(datagram.data(), datagram.size()); QDataStream in(&datagram, QIODevice::ReadOnly); int messageType; in >> messageType; QString userName,localHostName,ipAddress,message; QString time = QDateTime::currentDateTime() .toString("yyyy-MM-dd hh:mm:ss"); switch(messageType) { case Message: in >> userName >> localHostName >> ipAddress >> message; ui->messageBrowser->setTextColor(Qt::blue); ui->messageBrowser->setCurrentFont(QFont("Times New Roman",12)); ui->messageBrowser->append("[ " +userName+" ] "+ time); ui->messageBrowser->append(message); break; case NewParticipant: in >>userName >>localHostName >>ipAddress; newParticipant(userName,localHostName,ipAddress); break; case ParticipantLeft: in >>userName >>localHostName; participantLeft(userName,localHostName,time); break; case FileName: { in >> userName >> localHostName >> ipAddress; QString clientAddress, fileName; in >> clientAddress >> fileName; hasPendingFile(userName, ipAddress, clientAddress, fileName); break; } case Refuse: { in >> userName >> localHostName; QString serverAddress; in >> serverAddress; QString ipAddress = getIP(); if(ipAddress == serverAddress) { server->refused(); } break; } } } } // 处理新用户加入 void Widget::newParticipant(QString userName, QString localHostName, QString ipAddress) { bool isEmpty = ui->userTableWidget->findItems(localHostName, Qt::MatchExactly).isEmpty(); if (isEmpty) { QTableWidgetItem *user = new QTableWidgetItem(userName); QTableWidgetItem *host = new QTableWidgetItem(localHostName); QTableWidgetItem *ip = new QTableWidgetItem(ipAddress); ui->userTableWidget->insertRow(0); ui->userTableWidget->setItem(0,0,user); ui->userTableWidget->setItem(0,1,host); ui->userTableWidget->setItem(0,2,ip); ui->messageBrowser->setTextColor(Qt::gray); ui->messageBrowser->setCurrentFont(QFont("Times New Roman",10)); ui->messageBrowser->append(unCodec->toUnicode("%1 在线").arg(userName)); ui->userNumLabel->setText(unCodec->toUnicode("在线人数:%1").arg(ui->userTableWidget->rowCount())); sendMessage(NewParticipant); } } // 处理用户离开 void Widget::participantLeft(QString userName, QString localHostName, QString time) { int rowNum = ui->userTableWidget->findItems(localHostName, Qt::MatchExactly).first()->row(); ui->userTableWidget->removeRow(rowNum); ui->messageBrowser->setTextColor(Qt::gray); ui->messageBrowser->setCurrentFont(QFont("Times New Roman", 10)); ui->messageBrowser->append(unCodec->toUnicode("%1 在 %2 离开!").arg(userName).arg(time)); ui->userNumLabel->setText(unCodec->toUnicode("在线人数:%1").arg(ui->userTableWidget->rowCount())); } // 获取ip地址 QString Widget::getIP() { QList list = QNetworkInterface::allAddresses(); foreach (QHostAddress address, list) { if(address.protocol() == QAbstractSocket::IPv4Protocol) return address.toString(); } return 0; } // 获取用户名 QString Widget::getUserName() { QStringList envVariables; envVariables messageTextEdit->setFocus(); return msg; } // 发送消息 void Widget::on_sendButton_clicked() { sendMessage(Message); } // 获取要发送的文件名 void Widget::getFileName(QString name) { fileName = name; sendMessage(FileName); } // 传输文件按钮 void Widget::on_sendToolBtn_clicked() { if(ui->userTableWidget->selectedItems().isEmpty()) { QMessageBox::warning(0, unCodec->toUnicode("选择用户"), unCodec->toUnicode("请先从用户列表选择要传送的用户!")/**/, QMessageBox::Ok); return; } server->show(); server->initServer(); } // 处理是否接收文件 void Widget::hasPendingFile(QString userName, QString serverAddress, QString clientAddress, QString fileName) { QString ipAddress = getIP(); if(ipAddress == clientAddress) { int btn = QMessageBox::information(this,unCodec->toUnicode("接受文件"), unCodec->toUnicode("文件来自于%1(%2):%3,是否接受?") .arg(userName).arg(serverAddress).arg(fileName), QMessageBox::Yes,QMessageBox::No); if (btn == QMessageBox::Yes) { QString name = QFileDialog::getSaveFileName(0,unCodec->toUnicode("保存文件"),fileName); if(!name.isEmpty()) { TcpClient *client = new TcpClient(this); client->setFileName(name); client->setHostAddress(QHostAddress(serverAddress)); client->show(); } } else { sendMessage(Refuse, serverAddress); } } } // 更改字体族 void Widget::on_fontComboBox_currentFontChanged(QFont f) { ui->messageTextEdit->setCurrentFont(f); ui->messageTextEdit->setFocus(); } // 更改字体大小 void Widget::on_sizeComboBox_currentIndexChanged(QString size) { ui->messageTextEdit->setFontPointSize(size.toDouble()); ui->messageTextEdit->setFocus(); } // 加粗 void Widget::on_boldToolBtn_clicked(bool checked) { if(checked) ui->messageTextEdit->setFontWeight(QFont::Bold); else ui->messageTextEdit->setFontWeight(QFont::Normal); ui->messageTextEdit->setFocus(); } // 倾斜 void Widget::on_italicToolBtn_clicked(bool checked) { ui->messageTextEdit->setFontItalic(checked); ui->messageTextEdit->setFocus(); } // 下划线 void Widget::on_underlineToolBtn_clicked(bool checked) { ui->messageTextEdit->setFontUnderline(checked); ui->messageTextEdit->setFocus(); } // 颜色 void Widget::on_colorToolBtn_clicked() { color = QColorDialog::getColor(color, this); if (color.isValid()) { ui->messageTextEdit->setTextColor(color); ui->messageTextEdit->setFocus(); } } void Widget::currentFormatChanged(const QTextCharFormat &format) { ui->fontComboBox->setCurrentFont(format.font()); // 如果字体大小出错(因为我们最小的字体为12),使用15 if (format.fontPointSize() < 12) { ui->sizeComboBox->setCurrentIndex(3); } else { ui->sizeComboBox->setCurrentIndex( ui->sizeComboBox ->findText(QString::number(format.fontPointSize()))); } ui->boldToolBtn->setChecked(format.font().bold()); ui->italicToolBtn->setChecked(format.font().italic()); ui->underlineToolBtn->setChecked(format.font().underline()); color = format.foreground().color(); } // 保存聊天记录 void Widget::on_saveToolBtn_clicked() { if (ui->messageBrowser->document()->isEmpty()) { QMessageBox::warning(0, unCodec->toUnicode("等待"), unCodec->toUnicode("聊天记录为空,无法保存!")/*!*/, QMessageBox::Ok); } else { QString fileName = QFileDialog::getSaveFileName(this, unCodec->toUnicode("保存聊天记录"), unCodec->toUnicode("聊天记录"), unCodec->toUnicode("文本(*.txt);;所有文件(*.*)")); if(!fileName.isEmpty()) saveFile(fileName); } } // 保存聊天记录 bool Widget::saveFile(const QString &fileName) { QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, unCodec->toUnicode("保存文件"), unCodec->toUnicode("无法保存文件! %1:\n %2").arg(fileName) .arg(file.errorString())); return false; } QTextStream out(&file); out messageBrowser->toPlainText(); return true; } // 清空聊天记录 void Widget::on_clearToolBtn_clicked() { ui->messageBrowser->clear(); } // 退出按钮 void Widget::on_exitButton_clicked() { close(); } // 关闭事件 void Widget::closeEvent(QCloseEvent *e) { sendMessage(ParticipantLeft); QWidget::closeEvent(e); } //重绘事件 void Widget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.drawPixmap(rect(),QPixmap("://images/moutain.jpg"),QRect()); } bool Widget::eventFilter(QObject *target, QEvent *event) { if(target == ui->messageTextEdit) //可替换 { if(event->type() == QEvent::KeyPress)//回车键 { QKeyEvent *k = static_cast(event); if(k->key() == Qt::Key_Return) { on_sendButton_clicked(); //替换为需要响应的函数事件,以这里的按钮为例 return true; } } } return QWidget::eventFilter(target,event); } 5.下载地址

积分下载



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3