Qt实现简易聊天室

发布于:2023-01-19 ⋅ 阅读:(438) ⋅ 点赞:(0)

目录

一、界面展示(界面用ui 设计)

 群成员展示界面( denglu)

   聊天界面展示( widget )

二、代码展示 (所有代码非原创)

 denglu.h和widget.h

 denglu.cpp、main.cpp、widget.cpp

三、软件制作


一、界面展示(界面用ui 设计)

 群成员展示界面( denglu)

 

   聊天界面展示( widget )

二、代码展示 (所有代码非原创)

 denglu.h和widget.h

#ifndef DENGLU_H
#define DENGLU_H

#include <QWidget>

namespace Ui {
class denglu;
}

class denglu : public QWidget
{
    Q_OBJECT

public:
    explicit denglu(QWidget *parent = nullptr);
    ~denglu();

private:
    Ui::denglu *ui;
    QVector<bool> IsShow;
};

#endif // DENGLU_H

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QUdpSocket>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent,QString name);
    //重写关闭事件
    void closeEvent(QCloseEvent *);
     enum Msgtype{Msg,UserEnter,UserLeft};//枚举 分别代表 普通信息 用户进入 用户离开
     void sndMsg(Msgtype type);//广播udp信息
     QString getName();//获取名字
     QString getMsg();//获取聊天信息
     void userEnter(QString username);//处理用户进入
     void userLeft(QString username,QString time);//处理用户离开
     void ReceiveMessage();   //接受UDP消息
    ~Widget();
signals:

    void closeWidget();

private:
    Ui::Widget *ui;
    QString myname;
    quint16 port;//端口
    QUdpSocket *udpSocket;//udp 套接字
};

#endif // WIDGET_H

 denglu.cpp、main.cpp、widget.cpp

#include "denglu.h"
#include "ui_denglu.h"
#include<QIcon>
#include<QToolButton>
#include"widget.h"
#include<QMessageBox>

denglu::denglu(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::denglu)
{
    ui->setupUi(this);
    //设置图标
    //路径: 冒号+前缀+路径
    this->setWindowIcon(QIcon(":/imagine/qq.jpg"));
    //设置名称
    this->setWindowTitle("qq 2022");
    QList<QString> nameList;
    nameList<<"泼猴"<<"哪吒"<<"菩萨"<<"玉帝老2"<<"如来老6"<<"师傅"<<"偷吃人参果"<<"沙僧"<<"小白";
    QStringList iconNameList; //图标资源列表
    iconNameList << "1"<< "2" <<"3" <<"4"<< "5"<<"6"<<"7"<<"8"<<"9";
    QVector< QToolButton *> vector;
    for(int i=0;i<9;i++)
    {
        QToolButton *btn=new QToolButton(this);
        //加载图标
        btn->setIcon(QPixmap(QString(":/imagine/%1.jpg").arg(iconNameList[i])));
        //设置图片大小
        btn->setIconSize(QPixmap(QString(":/imagine/%1.jpg").arg(iconNameList[i])).size());
        //设置网名
        btn->setText(QString("%1").arg(nameList[i]));
        //设置为透明
        btn->setAutoRaise(true);
        //设置显示格式
        btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
        //放到vlayout布局中
        ui->vlayout->addWidget(btn);
        vector.push_back(btn);
        IsShow.push_back(false);

    }
    for(int i=0;i<9;i++)
    {
        connect(vector[i],&QToolButton::clicked,[=](){
            if(IsShow[i])
            {
                QMessageBox::warning(this,"警告","该聊天框已被打开!");
                return;
            }
            IsShow[i]=true;
            Widget *widget=new Widget(nullptr,vector[i]->text());
            widget->setWindowIcon(vector[i]->icon());
            widget->setWindowTitle(vector[i]->text());
            widget->show();
            //关闭时将对应的IsShow变为false;
            connect(widget,&Widget::closeWidget,this,[=](){
                IsShow[i]=false;
            });
        });
    }

}
denglu::~denglu()
{
    delete ui;
}
#include "widget.h"
#include <QApplication>
#include"denglu.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //Widget w;
    //w.show();
    denglu b;
    b.show();
    return a.exec();
}
#include "widget.h"
#include "ui_widget.h"
#include<QDataStream>
#include<QMessageBox>
#include<QDateTime>
#include<QComboBox>
#include<QColorDialog>
#include<QFileDialog>

Widget::Widget(QWidget *parent ,QString name) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    myname=name;

    this->port=9999;
    this->udpSocket=new QUdpSocket(this);

    udpSocket->bind(port,QUdpSocket::ShareAddress |QUdpSocket::ReuseAddressHint);

    //
    connect(udpSocket,&QUdpSocket::readyRead,this,&Widget::ReceiveMessage);

    //连接发送按钮
    connect(ui->sendBtn,&QPushButton::clicked,[=](){
        sndMsg(Msg);
    });

    //新用户进入
    sndMsg(UserEnter);

    connect(ui->exitBtn,&QPushButton::clicked,[=](){
        this->close();
    });
    //字体类型
    connect(ui->fontCbx,&QFontComboBox::currentFontChanged,[=](const QFont &font){
        ui->msgTxtEdit->setFontFamily(font.toString());
        ui->msgTxtEdit->setFocus();
    });
    //字体大小
    void (QComboBox:: * sizebtn)(const QString &text)=&QComboBox::currentTextChanged;
    connect(ui->sizeCbx,sizebtn,[=](const QString &text){
        ui->msgTxtEdit->setFontPointSize(text.toDouble());
        ui->msgTxtEdit->setFocus();
    });
    //字体的加粗
    connect(ui->boldTBtn,&QToolButton::clicked,[=](bool checked){
        if(checked)
        {
            ui->msgTxtEdit->setFontWeight(QFont::Bold);
        }
        else {
            ui->msgTxtEdit->setFontWeight(QFont::Normal);
        }
    });
    //字体倾斜
    connect(ui->italicTbtn,&QToolButton::clicked,[=](bool checked){
        ui->msgTxtEdit->setFontItalic(checked);
        ui->msgTxtEdit->setFocus();
    });
    //字体下划线
    connect(ui->underlineTBtn,&QToolButton::clicked,[=](bool checked){
        ui->msgTxtEdit->setFontUnderline(checked);
        ui->msgTxtEdit->setFocus();
    });
    //清空功能
    connect(ui->clearTBtn,&QToolButton::clicked,[=](){
        ui->msgBrowser->clear();
    });
    connect(ui->colorTBtn,&QToolButton::clicked,[=](){
        QColor color=QColorDialog::getColor(color,this);

        ui->msgTxtEdit->setTextColor(color);
    });
    connect(ui->saveTBtn,&QToolButton::clicked,[=](){
        if(ui->msgBrowser->toPlainText().isEmpty())
        {
            QMessageBox::warning(this,"警告","警告!保存内容不能为空!");
            return;
        }
        QString filename=QFileDialog::getSaveFileName(this,"保存聊天记录","聊天记录","(*.txt)");
        if(!filename.isEmpty())
        {
            QFile file(filename);
            file.open(QIODevice::WriteOnly | QFile::Text);
            QTextStream stream(&file);
            stream<<ui->msgBrowser->toPlainText();
            file.close();
        }
    });
}

void Widget::closeEvent(QCloseEvent *e)  //重写离开事件
{
    emit this->closeWidget();
    sndMsg(UserLeft);
    udpSocket->close();
    udpSocket->destroyed();
    QWidget::closeEvent(e);
}

void Widget::sndMsg(Widget::Msgtype type)
{
    QByteArray array;
    QDataStream stream(&array,QIODevice::WriteOnly);
    stream<<type<<this->getName();
    switch (type)
    {
    case Msg:
        if(ui->msgTxtEdit->toPlainText()=="")
        {
            QMessageBox::warning(this,"警告","发送的聊天内容不能为空!");
            return;
        }
        stream<<this->getMsg();
        break;
    case UserEnter:
        break;
    case UserLeft:
        break;
    }
    //书写报文
    udpSocket->writeDatagram(array.data(),array.size(),QHostAddress::Broadcast,this->port);
}

QString Widget::getName()   //获取名字
{
    return this->myname;
}

QString Widget::getMsg()
{
    QString msg=ui->msgTxtEdit->toHtml();
    ui->msgTxtEdit->clear();
    ui->msgTxtEdit->setFocus();
    return msg;
}
void Widget::userEnter(QString username)      //处理用户进入
{
    bool IsEmpty=ui->tableWidget->findItems(username,Qt::MatchExactly).isEmpty();

    if(IsEmpty)
    {
        QTableWidgetItem *table=new QTableWidgetItem(username);
        ui->tableWidget->insertRow(0);
        ui->tableWidget->setItem(0,0,table);
        ui->msgBrowser->setTextColor(QColor(Qt::gray));
        ui->msgBrowser->append(username+"已上线");
        ui->userNumLbl->setText(QString("在线人数:%1").arg(ui->tableWidget->rowCount()));
        sndMsg(UserEnter);
    }
}

void Widget::userLeft(QString username, QString time)  //处理用户离开
{
    bool IsEmpty=ui->tableWidget->findItems(username,Qt::MatchExactly).isEmpty();
    if(!IsEmpty)
    {
        int row=ui->tableWidget->findItems(username,Qt::MatchExactly).first()->row();

        ui->tableWidget->removeRow(row);

        ui->msgBrowser->append(QString("%1用户于%2离开").arg(username).arg(time));

         ui->userNumLbl->setText(QString("在线人数:%1").arg(ui->tableWidget->rowCount()));
    }
}

void Widget::ReceiveMessage()    //接收udp消息
{
    qint64 size=udpSocket->pendingDatagramSize();
    int mysize= static_cast<int>(size);
    QByteArray *array=new QByteArray(mysize,0);
    udpSocket->readDatagram((*array).data(),size);
    QDataStream stream(array,QIODevice::ReadOnly);
    int mytype;
    QString name,msg;//用户名 聊天内容
    QString time=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    stream>>mytype;
    switch (mytype) {
    case Msg:
        stream>>name>>msg;
        ui->msgBrowser->setTextColor(QColor(Qt::blue));
        ui->msgBrowser->append("["+name+"]"+time);
        ui->msgBrowser->append(msg);
        break;
    case UserLeft:
        stream>>name;
        userLeft(name,time);
        break;
    case UserEnter:
        stream>>name;
        userEnter(name);
        break;
    }

}
Widget::~Widget()
{
    delete ui;
}

注意:群成员用户界面的用户头像需要自己建立一个资源文件夹保存。方法如下

 

 

 

 

 

 

 

 

三、软件制作

 

选择Release构建(平常我们检查功能是否实现,是默认Debug构建),这样构建出来的 .exe 比Debug构建的小

  

 

下面所有图片中的 .exe 都是新建的文件夹下的  .exe 

 

 

 

 这样一个软件就诞生了。但是新生成的这个 .exe 只能在本机上运行,如果想要能将这个软件传输给其他人,就需要使用 Enigma Virtual Box 这个打包工具。

 

 

 

这样一款可传输的pc端的软件就诞生了,只是没有图标。哈哈哈哈哈。自己努力做出来的软件没有图标也一样nice。 如果需要图标的,可以在网上搜索怎样添加图标。

完美!!!!!!!!!!!!!!!!!!

 

 

 

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到