QT学习之QQ聊天案例

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;//QStringList  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);}//对8个按钮添加信号和槽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;//构造聊天窗口,参数1:顶层方式弹出  参数2:窗口名字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();});//加粗//设置选中按钮生效,点击一次发送TRUE,再次点击发送FALSEui->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);//打开模式加换行操作 QIODevice::Textfile.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)//广播UDP消息
{//发送的消息分为三种类型, 做分段处理 第一段类型   第二段 用户名     第三段 具体内容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)
{//更新右侧tablebool 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)
{//更新右侧tablebool 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();//因为有一些加粗设置,所以需要把内容转为htmlui->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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15456.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【教学类-36-01】Midjounery生成的四张图片切片成四张小图

作品展示&#xff1a; 把一张正方形图片的四个等大小图切割成四张图片 背景需求 最近在学习ChatGPT的绘画&#xff08;midjounery AI艺术&#xff09; 我想给中班孩子找卡通动物图片&#xff08;黑白线条&#xff09;&#xff0c;打印下来&#xff0c;孩子们练习描边、涂色…

chatgpt赋能python:Python校验身份证号码真伪

Python校验身份证号码真伪 身份证号码是我们日常生活中非常重要的证件&#xff0c;但也有一些人从事非法活动&#xff0c;对身份证号码进行伪造或者篡改。为了保护公民的合法权益&#xff0c;我们需要使用技术手段来校验身份证号码真伪。而Python作为一种广泛应用于数据处理和…

【科普级别:刚出炉的ChatGPT三连问】

科普级别&#xff1a;刚出炉的ChatGPT三连问 前言【ChatGPT是什么&#xff1f;对我们的生活有什么影响&#xff1f;】【中国为什么不能使用ChatGPT&#xff1f;美国想让中国用户使用吗&#xff1f;】【通义千问、文心一言、ChatGPT你更看好哪一个&#xff1f;】 前言 有些人连C…

又一个国内类ChatGPT模型?【秘塔科技上线自研LLM大模型「对话写作猫」】

又一个国内类ChatGPT模型&#xff1f;【秘塔科技上线自研LLM大模型「对话写作猫」】 &#xff08;马上被打脸 ~ ~&#xff09; 一直期待中国有没有类ChatGPT产品可以出现。 昨天&#xff0c;2023年2月27日&#xff0c;秘塔科技上线了自研LLM大模型「对话写作猫」&#xff0c;…

小白入门区块链(通俗易懂)

区块链基础入门 什么是区块链 科技层面解释 数学&#xff0c;密码学&#xff0c;互联网&#xff0c;计算机编程官方解释 区块链是一个分布式的共享账本和数据库&#xff0c;具有去中心化&#xff0c;不可篡改&#xff0c;全程留痕&#xff0c;可以追溯&#xff0c;集体维护&am…

2023年加密行业会更难吗?欧科云链研究院“七大趋势预测”

回望2022&#xff0c;加密行业遭遇了种种不可控因素而导致的艰难险阻&#xff0c;也在变革与发展中孕育着生机与活力。 这一年&#xff0c;我们亲眼目睹了Luna暴雷&#xff0c;三箭资本、FTX这些曾经被认为“大而不倒”的机构接连倒下&#xff0c;市场信心严重受挫&#xff1b…

​别急着骂百度,来看看大模型到底怎么用

文&#xff5c;光锥智能&#xff0c;作者&#xff5c;周文斌&#xff0c;编辑&#xff5c;王一粟 GPT-4惊艳亮相后&#xff0c;压力来到百度这边。 上台后的李彦宏和百度CTO王海峰都略显紧张&#xff0c;这在多年百度相关活动中还是非常少见。李彦宏坦言&#xff0c;“文心一言…

Node.js 高级编程之 Stream(我是跟 ChatGPT 学会的)

前言 在做 SSR Stream Render 的时候遇到了 Node.js 的 Stream&#xff0c;但是对其总是一知半解。正好最近 ChatGPT 很火&#xff0c;找他学一学吧&#xff0c;没想到真的把我教会了。PS&#xff1a;文末有跟 ChatGPT 的精彩对话&#xff08;请忽略我稀烂的英语&#xff09;。…

《不想放水》

原创&#xff1a;刘教链 * * * 由刘教链和ChatGPT共同填词。原曲&#xff1a;S.H.E.《不想长大》。 为什么就是找不到放水的证据呀 为什么救助的银行都不愿退市啊 我并不希望他拥有比特币和黄金 我惊讶的是假话竟然会变成谎话 为什么美元印钞机要转的那么快 为什么通胀和失业率…

存储器介绍

文章目录 存储系统基本概念存储器的层次存储器的分类存储器的性能指标 主存储器半导体元件的原理存储芯片的基本原理寻址 DRAM和SRAMDRAM的刷新DRAM的地址复用 只读存储器ROM主存储器和CPU的连接位扩展字扩展字位同时扩展补充 双端口RAM和多模块存储器双端口RAM解决多核CPU访存…

OpenAI文档翻译——在不通的场景下如何更好的设计ChatGPT提示词

概述 OpenAI可以被广泛的应用于各种任务&#xff0c;他为各种模型提供使用简单而功能强大的API。你可以输入一些文本作为提示词&#xff0c;OpenAI则会生成对应的提示词补全&#xff0c;在使用过程中这就是会话形式以及能够记住上下文的体现。探索如何生成提示词的最好方法就是…

如何使用ChatGPT 写官方声明?

上海车展宝马Mini展台被指区别对待中外访客&#xff0c;向外国访客送冰淇淋&#xff0c;中国访客索要时则说“没有”&#xff0c;此事引发争议。 对此&#xff0c;宝马官方也发布了官方致歉声明&#xff0c;网友看到声明后&#xff0c;纷纷发布自己的看法&#xff0c;有网友还…

独家专访:OpenAI 的 Sam Altman 谈 ChatGPT 以及通用人工智能如何“打破资本主义”

来源: AI前线 作为 OpenAI 的首席执行官&#xff0c;Sam Altman 领导的这家初创公司是正在快速增长的生成式 AI 行业中最热门且最受关注的一家。在 1 月中旬参观了 OpenAI 的旧金山办事处后&#xff0c;福布斯采访了这位最近不太愿意在媒体上抛头露面的投资者和企业家&#x…

ChatGPT is not all you need,一文看尽SOTA生成式AI模型:6大公司9大类别21个模型全回顾(三)

文章目录 ChatGPT is not all you need&#xff0c;一文看尽SOTA生成式AI模型&#xff1a;6大公司9大类别21个模型全回顾&#xff08;三&#xff09;Text-to-Text 模型ChatGPTLaMDAPEERMeta AI Speech from Brain Text-to-Code 模型CodexAlphacode Text-to-Science 模型Galacti…

千万级入口服务[Gateway]框架设计(三:分层模式)

本文将以技术调研模式编写&#xff0c;非技术同学可跳过。 文章目录 背景分层分发Handle分发hook分发并发分层 管道ChannelDemo 实现 小结 附录 背景 基于组件(插件)模式设计构建的入口服务实现中&#xff0c;使用 Go 原生包 plugin 的时候&#xff0c;会存在功能缺陷问题&am…

ChatGPT配合两款神器,1分钟生成流程图

流程图&#xff0c;工作上再正常不过的一种图形&#xff0c;常见制图方法对比&#xff1a; 传统手动制图&#xff1a;耗时耗力&#xff0c;迁移性差AI 辅助制图&#xff1a;使用自然语言提出需求&#xff0c;零基础快速制图 几款常见的我在用的在线绘图工具推荐&#xff1a; Pr…

面向对象实现游戏聊天中的敏感词屏蔽功能,将敏感词汇用星号***替换

import java.util.Scanner;//新建一个类 public class Replace {// 定义一个字符串String commons;// 建一个替换的方法public void replace() { //控制台输入Scanner sc new Scanner(System.in);// 提示输出&#xff08;为方便功能实现&#xff0c;此处提示内定的敏感词汇&am…

DreamGPT:让ChatGPT活在梦里!利用幻觉来激发创意灵感

本文来源 新智元 编辑&#xff1a;LRS 【新智元导读】语言模型幻觉从bug变feature&#xff01; ChatGPT最为人诟病的缺陷就是「胡编乱造」了&#xff0c;可以一本正经地讲一段林黛玉倒拔垂杨柳的故事。 对于真正想了解「林黛玉」或「倒拔垂杨柳」的人来说&#xff0c;这段回答…

这五个问题一下就看出阿里通义千问和ChatGPT的差距了

前言 阿里通义千问申请过了&#xff0c;为了看看达到了什么水平&#xff0c;于是我问题了5个ChatGPT回答过的问题1&#xff0c;这五个问题网上都是没有的&#xff0c;是我自己想出来的。 问题一:小明说今天他吃了一只公鸡蛋&#xff0c;请问小明诚实吗&#xff1f; ChatGPT 这…

chatgpt赋能python:Python模拟终端:打造简单易用的命令行工具

Python模拟终端&#xff1a;打造简单易用的命令行工具 在现代编程中&#xff0c;命令行工具被广泛使用。无论是开发、测试还是维护&#xff0c;都需要通过命令行工具完成。Python的灵活性和强大的库使得开发命令行工具变得更加容易。本文将介绍如何使用Python编写一个简单易用…