一、实验目的
设计一款携带多种功能的聊天软件,不仅可以聊天,也能修改字体,计时,绘画等等。
二、实验内容:
1)ui设计(满分15分)
2)画图、timer、多线程(满分20分)
3)数据库操作(满分15分)
4)TCP网络通信(满分40分) (客户端15分,多线程服务器25分)
三、实验环境
Qt Creator 4.2.1 (Community)
四、实验过程与运行结果
1)ui设计
图表 1聊天界面
头像是在网络上找的,其余图标都是自己绘制的,但由于设计时间过早,在后面完成代码的时候发现没有信息的数据库,所以这里的了解成员要改为查找地址。
图表 2设计界面2
这是设计的第二个界面,但是本来想要管理员链接服务端,但是因为项目的问题一直链接不上,排查问题找了很久都没有找到问题,所以这里设计的按钮其实是无法跳转的,所以就改为第一次的设计。
图表 3绘画界面
图表 4客户端界面
图表 5服务端界面
2)画图、timer、多线程
图表 6多线程聊天
可进行多人聊天,只要打开窗口就能够聊天,但如果其他人要接收的话,也需要打开聊天框,不然就不能够接收到信息。
图表 7保存聊天记录
这里为了合理化也设计了字体样式的更改,保存,清空等等,但是颜色字号因为不太理解所以没有做成功,但加粗等成功了。
图表 8保存的聊天记录
图表 9修改字体样式
图表 10警告
为了不出现重复聊天框的BUG,所以要设置一个警告。
图表 11绘图界面
这里只绘制了一个圈和字体,但也可以实现其他的绘画,比如画直线等等,但需要在代码中加入,这里没有加是因为我觉得这样设计会比较好看。
图表 12绘画界面弹出
只要点击来画画吧,就会弹出绘画的这个窗口,这里本来想设计成后面的那些窗口都消失,但发现这样不太明显,就将那条代码删除了。
图表 13计时器
点击计时器按钮,就会跳转到计时器的这个页面来,点击开始就能够开始计时,停止就停止计时,重置就是重新开始。
图表 14点击重置后
点击重置后,时间就归零了。
3)数据库操作
图表 15数据库登录
这里是老师上课讲解的内容,这里进行了一个结合,只要点击右下方的按钮,就能够弹出这个页面,也就是“小蜜蜂数据”,接着就能够链接数据库查询信息了。
图表 16查询信息页面
因为没有数据库,所以这里用的是老师之前教课时所使用的,自己也尝试建立数据库,发现了很多问题,诸如数据的问题,要创建ID类但是一直无法设置好,导致程序出现故障等等。
图表 17重新建立数据库界面
因为原本数据库不太适合我的聊天软件,于是进行了更改,这样就能够查询好友的信息,比较匹配我的聊天软件。
4)TCP网络通信
图表 18同时打开服务端和客户端
能够运行服务端和客户端,界面上的LOGO是我设计的小蜜蜂。
图表 19多线程链接
两个客户端能够和服务端链接并且发送消息。
图表 20单线程链接
以下是主代码展示:【代码不全】
(1)Widegt.cpp
#include "widget.h"
#include "ui_widget.h"
#include"draw.h"
#include "mytime.h"
#include "mydb.h"
#include <QString>
#include <QDataStream>
#include <QMessageBox>
#include <QDateTime>
#include <QDebug>
#include <QFont>
#include <QColor>
#include <QColorDialog>
#include <QFileDialog>
#include <QTextStream>
#include <QFontDialog>
#include <QPushButton>
Widget::Widget(QWidget *parent ,QString name) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
myname=name;
this->ppage2=new draw;//实例化绘画页面S
connect(ui->drawBtn,&QPushButton::clicked,[=](){
//this->hide();
this->ppage2->show();//显示
});
this->ppage3=new mytime;
connect(ui->timerBtn,&QPushButton::clicked,[=](){
this->ppage3->show();
});
this->ppage4=new mydb;
connect(ui->dataBtn,&QPushButton::clicked,[=](){
this->ppage4->show();
});
this->port=0032;
this->udpSocket=new QUdpSocket(this);
udpSocket->bind(this->port,QUdpSocket::ShareAddress |QUdpSocket::ReuseAddressHint);
connect(udpSocket,&QUdpSocket::readyRead,this,&Widget::ReceiveMessage);
connect(ui->sendBtn,&QPushButton::clicked,[=](){
sndMsg(Msg);
});
}
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::ReceiveMessage()
{
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->setCurrentFont(QFont("Times New Roman",10));
ui->msgBrowser->append(("["+name+"]"+time));
ui->msgBrowser->append(msg);
break;
case UserEnter:
stream>>name;
// userEnter(name);
break;
case UserLeft:
stream>>name;
// userLeft(name,time);
break;
}
//字体改变
connect(ui->fontCbx,&QFontComboBox::currentFontChanged,[=](const QFont &font){
ui->msgTxtEdit->setFontFamily(font.toString());
ui->msgTxtEdit->setFocus();
});
//字体大小
<