利用QT写的局域网聊天工具(客户端)

一、客户端涉及到UI界面的跳转和回显

代码实现思路:

1.1、界面跳转通过信号槽实现,登录界面完成后,发送信号给主界面,同时主界面通过信号函数获取服务端信息,从而建立socket,实现网络通信;

1.2、数据库记录现有用户列表,并建立对应的UI索引,因为每次在主界面双击时,就要弹出新的UI以实现多对多聊天;

1.3、主界面控制socket的收发,socket收发后依据字符流控制消息流向哪个打开UI界面,实现多对多聊天消息分发及隔离;

1.4、运行后的效果如图:

                                            

                        图1.登录界面                                                               图2.主界面 

                                 图3.聊天界面

二、代码如下:

salite记录数据相关文件:

cpp文件:(其实和服务端的相同)

/*--------------------------------------------------------
* Author      : Firdin
* E-mail      : firdin@yeah.net
* File Name   : server_sqlite.c
* Created Time: 2017年10月12日 星期四 15时27分11秒
* Introduction:
* 
*-------------------------------------------------------*/

#include "server_sqlite.h"
#include<QDebug>
#include<QString>

bool server_sqlite::sqlite_init()
{
    if(QSqlDatabase::contains("qt_sql_default_connection"))
        my_db=QSqlDatabase::database("qt_sql_default_connection");
    else
        my_db=QSqlDatabase::addDatabase("QSQLITE");//创建sqlite数据库文件
    if(!my_db.isValid())
    {
        qDebug()<<"数据库创建失败"<<endl;
        return false;
    }

    my_db.setDatabaseName("E:\\user_client.db");//将数据库文件存放在C盘,且名字为user_info.db
    if(!my_db.open())//判断数据库打开是否正常
    {
        qDebug()<<"数据库文件打开失败";
        return false;
    }
    else
    {
        qDebug()<<"数据库文件已打开";
    }
     QSqlQuery search;//数据库语句执行
    temp="create table user(id INT,name VARCHAR(15),IP VARCHAR(15),state VARCHAR(8))";//数据库表单:ID、用户名、IP地址、在线与否

    //qDebug()<<"创建表单:"<<temp;

    if(!search.exec(temp))//判断数据库语句执行是否正常
    {
        qDebug()<<"表单创建失败,原因:已存在数据库表单或文件读取错误,请检查!!";
    }
     sqlite_delete_all();
    return true;
}

bool server_sqlite::sqlite_insert(int id_s,QString name_t,QString  IP_t)//插入新的用户信息到数据库表单,格式:用户名、用户IP地址(字符串形式)
{
    temp.clear();
    temp.sprintf("insert into user values(%d,'%s','%s','在线')",id_s,name_t.toStdString().data(),IP_t.toStdString().data());

    QSqlQuery search;//数据库语句执行

    if(!search.exec(temp))
    {
         qDebug()<<"插入数值失败,请检查!!";
         return false;
    }
    count++;
    return true;
}

bool server_sqlite::sqlite_delete(QString name_m)//删除表单中某一个元素
{
    temp.clear();
    temp.sprintf("delete from user where name = '%s'",name_m.toStdString().data());
    QSqlQuery search;//数据库语句执行
    if(!search.exec(temp))
    {
         qDebug()<<"删除数值失败,请检查!!";
         return false;
    }
    return true;
}

bool server_sqlite::sqlite_delete_all()//删除表单中所有元素
{
    temp.clear();
    temp="delete from user";
    QSqlQuery search;//数据库语句执行
    if(!search.exec(temp))
    {
         qDebug()<<"删除所有数值失败,请检查!!";
         return false;
    }
    return true;
}

QString* server_sqlite::sqlite_search(QString name_s)//依据用户名查找对应的信息
{
    QString *des=new QString;
    temp.clear();
    temp.sprintf("select id,name,IP,state from user where name = '%s' ",name_s.toStdString().data());
    QSqlQuery search;//数据库语句执行
    if(!search.exec(temp))
    {
         qDebug()<<"查找指定数值失败,请检查!!";
         return NULL;
    }
    while(search.next())
    {
        *des+=search.value(1).toString()+"  "+search.value(2).toString()+"  "+search.value(3).toString()+"\n";
    }
    return des;
}

bool server_sqlite::sqlite_update(QString name_u,QString state_u)//修改用户在线信息
 {
     temp.clear();
     temp.sprintf("update user set state = '%s' where name = '%s'",state_u.toStdString().data(),name_u.toStdString().data());
     QSqlQuery search;//数据库语句执行
     if(!search.exec(temp))
     {
          qDebug()<<"修改指定用户状态失败,请检查!!";
          return false;
     }
     return true;
 }

QString* server_sqlite::sqlite_online_server()//显示当前在线用户信息
{
    QString *temp=new QString;
    QSqlQuery search;//数据库语句执行
    search.exec("select * from user");
    while(search.next())
    {
        if( "offline" != search.value(3))
        {
            //qDebug()<<"用户名:"<<search.value(1).toString()<<"IP地址:"<<search.value(2).toString()<<endl;
            *temp+=search.value(1).toString()+"  "+search.value(2).toString()+"\n";
        }
    }
    //qDebug()<<"原始信息拼接:"<<*temp;
    return temp;
}

QString* server_sqlite::sqlite_offline_server()//显示当前不在线用户信息
{
    QString *temp=new QString;
    QSqlQuery search;//数据库语句执行
    search.exec("select * from user");
    while(search.next())
    {
        if("online" != search.value(3))
            *temp+=search.value(1).toString()+"  "+search.value(2).toString()+"\n";
    }
   // qDebug()<<"不在线用户信息:"<<*temp;
    return temp;
}

 bool server_sqlite::sqlite_delete_table()//删除表单(表单为临时配置文件,因此可以删除)
 {
     temp.clear();
     temp.sprintf("drop table user");
     QSqlQuery search;//数据库语句执行
     if(!search.exec(temp))
     {
          qDebug()<<"删除表单失败,请检查!!";
          return false;
     }
     return true;
 }

 int server_sqlite::sqlite_search_id(QString name_src)
 {
     temp.clear();
     temp.sprintf("select id from user where name = '%s'",name_src.toStdString().data());
     QSqlQuery search;
     //qDebug()<<temp;
     if(!search.exec(temp))
     {
         qDebug()<<"表单查询失败,请检查!!";
         return -1;
     }
     if(search.first())
     {
        //qDebug()<<"所查ID为:"<<search.value(0).toInt();
         return search.value(0).toInt();
     }
     return -1;
 }

 QString* server_sqlite::sqlite_search_IP(QString name_s)//查找制定用户的IP地址
 {
     QString *t=new QString;
     temp.clear();
     temp.sprintf("select IP from user where name = '%s'",name_s.toStdString().data());
     QSqlQuery search;
     //qDebug()<<temp;
     if(!search.exec(temp))
     {
         qDebug()<<"表单查询失败,请检查!!";
         return NULL;
     }
     if(search.first())
     {
        //qDebug()<<"所查IP为:"<<search.value(0).toInt();
         *t=search.value(0).toString();
         return t;
     }
     return NULL;
 }

H文件

#ifndef server_sqlite_H
#define server_sqlite_H

#include <QSqlDatabase>
#include <QSqlRecord>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>

class server_sqlite //无继承的类(独立数据库操作类)
{

private:
    QSqlDatabase my_db;//用户数据表单建立
    int count;//用户在线人数
    QString temp;//用于拼接字符用的临时变量
    QString output;//用于输出用户信息
public:
    explicit server_sqlite()
    {
        count=0;
        temp.clear();
    }
    bool sqlite_init();//初始化数据库用成员函数
    bool sqlite_insert(int id_s,QString name_t,QString  IP_t);//插入数据
    bool sqlite_delete(QString name_m);//删除一条数据
    bool sqlite_delete_all();//删除所有的数据
    QString* sqlite_search(QString name_s);//查找指定用户数据
    QString* sqlite_search_IP(QString name_s);//查找制定用户的IP地址
    bool sqlite_update(QString name_u,QString state_u);//修改指定用户的在线与否信息
    QString* sqlite_online_server();//输出在线用户信息,通过判断state是否是online
    QString* sqlite_offline_server();//输出历史用户(不在线但是有其信息)
    bool sqlite_delete_table();//删除表单(表单为临时配置文件,因此可以删除)
    int sqlite_search_id(QString name_src);//依据名字查询ID号,ID号在转发数据时需要用于查找QList中的socket对象,以达到准确转发消息
     ~server_sqlite()
    {
        my_db.close();
    }
};
#endif

登录UI的代码实现:

cpp代码实现:

#include "my_login.h"
#include "ui_my_login.h"
#include<QPainter>

My_Login::My_Login(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::My_Login)
{
    ui->setupUi(this);
    this->setFixedSize(318,264);//设置窗体大小固定
    this->setWindowTitle("登陆到服务器");
    Img=QImage(":/bk_login");
    //点击响应
    connect(ui->pushButton_login,SIGNAL(clicked(bool)),this,SLOT(slot_send()));
}

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

void My_Login::slot_send()//发送信息到主窗体(信号槽)
{
    if(ui->lineEdit_username->text().isEmpty() || ui->lineEdit_IPAddr->text().isEmpty() || ui->lineEdit_IP_Port->text().isEmpty())
    {
        QMessageBox::warning(this,"警告","请输入完整登陆信息后再登陆!",QMessageBox::Ok,QMessageBox::Cancel);
    }
    else
    {
        QString send_info;
        send_info+=ui->lineEdit_username->text()+":"+ui->lineEdit_IPAddr->text()+":"+ui->lineEdit_IP_Port->text();
        emit send_data(send_info);
    }
}
void My_Login::paintEvent(QPaintEvent *event)//绘制背景
{
    QPainter pt(this);  //定义一个在当前窗口画画的画家
    QImage drawing = Img.scaled(this->width(),this->height());
    pt.drawImage(0,0,drawing,0,0,this->width(),this->height());
    update();
}

H文件:

#ifndef MY_LOGIN_H
#define MY_LOGIN_H

#include <QDialog>

#include <QHostAddress>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QProcess>

#include<QTcpServer>
#include<QTcpSocket>

#include<QMessageBox>

#include<QImage>
#include<QPaintEvent>

namespace Ui {
class My_Login;
}

class My_Login : public QDialog
{
    Q_OBJECT

public:
    explicit My_Login(QWidget *parent = 0);
    void paintEvent(QPaintEvent *event);
    ~My_Login();

private:
    Ui::My_Login *ui;
    QImage Img;

signals:
    void send_data(QString);
private slots:
    void slot_send();
};

#endif // MY_LOGIN_H

聊天界面的实现:

cpp文件的实现:

#include "my_chart.h"
#include "ui_my_chart.h"
#include<QStringList>
#include<QMessageBox>
#include<QTextStream>

#include <QPainter>
#include <QPixmap>
My_Chart::My_Chart(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::My_Chart)
{
    ui->setupUi(this);
    this->setFixedSize(653,441);
    ui->textEdit_show_message->setReadOnly(true);
    //点击响应
    connect(ui->pushButton_send,SIGNAL(clicked(bool)),this,SLOT(slot_send_message()));
}

My_Chart::~My_Chart()
{
    delete ui;
}
void My_Chart::setIP_min(QString res)//显示本机IP地址和聊天对象的IP地址
{
    QStringList analysis=res.split(";");
    ui->label_show_mine->setText(analysis.at(0));//显示本机IP地址
    ui->label_show_other_side->setText(analysis.at(1));//显示对方的IP地址
}

void My_Chart::show_message(QString src)//接收主窗体的字符串并显示到聊天界面上去
{
    QStringList analysis=src.split(":");//依据符号对原始字符串进行分割
    ui->textEdit_show_message->append(analysis.at(0)+":\n"+analysis.at(1));//将对方的消息内容显示在窗体上
}

void My_Chart::set_names_client(QString src)//传送用户姓名和接收方姓名
{
    QStringList analysis=src.split(":");
    name_local=analysis.at(0);
    username=analysis.at(1);//设置用户名
}

void My_Chart::slot_send_message()//发送消息
{
    QString mess="message:";//消息拼接
    QString temp;//取出聊天内容
    temp.clear();
    QTextStream out(&temp);//从textEdit中读取内容
    out << ui->textEdit_input_message->toPlainText();//保存成为html格式//保存到文件中
    //qDebug()<<"对话框中的内容"<<temp;
    if(temp.isEmpty())
    {
        QMessageBox::warning(this,"提示","请输入消息后再尝试发送!!",QMessageBox::Ok,QMessageBox::Cancel);//没有输入消息则弹窗警示
        qDebug()<<"无消息可发送!!";
    }
    else
    {
        mess+=name_local+"|"+username+":"+temp;
        //qDebug()<<"发送的消息内容"<<mess;

        ui->textEdit_input_message->clear();//清除输入框中的字符
        QByteArray message;
        QDataStream out(&message,QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_5_7);
        out<<mess;
        qDebug() << "发送消息:" << mess;
        Socket_login->write(message);
        qDebug()<<"消息已发出!";
        ui->textEdit_show_message->append(name_local + ":\n" + temp);
    }
}

void My_Chart::set_Socket_local(QTcpSocket *Socket_src)
{
    Socket_login=Socket_src;
}
void My_Chart::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.drawPixmap(0,0,width(), height(),QPixmap(":/10.jpg"));
}

H文件实现:

#ifndef MY_CHART_H
#define MY_CHART_H

#include <QDialog>

#include <QHostAddress>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QProcess>

#include <QPainter>
#include <QPixmap>

#include<QTcpServer>
#include<QTcpSocket>

namespace Ui {
class My_Chart;
}

class My_Chart : public QDialog
{
    Q_OBJECT

public:
    explicit My_Chart(QWidget *parent = 0);
    void setIP_min(QString res);//显示本地IP地址(测试用)
    void show_message(QString src);//接收主窗体的字符串并显示到聊天界面上去
    void set_names_client(QString src);//传送聊天双方的名字
    void set_Socket_local(QTcpSocket *Socket_src);//将Socket传送过来,在聊天窗口实现发送消息,减轻主窗体的网络负担
    void paintEvent(QPaintEvent *event);
    ~My_Chart();

    /*
signals:
    void send_message(QString);
    */
private slots:
    void slot_send_message();//发送消息到一个指定的用户(指定用户为打开的聊天界面是和谁在聊天)


private:
    Ui::My_Chart *ui;
    QString username;//聊天对像的名字(用于发送信息)
    QString name_local;//本家姓名(发起聊天的我的用户名)
    QTcpSocket *Socket_login;//接受主窗体的网络文件描述符
};

#endif // MY_CHART_H

主界面的代码实现:

cpp文件实现:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QPicture>

#include<QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    user_count=2;
    current_user=0;
    this->setFixedSize(252,532);//设置窗体大小固定,数值源自UI设计图形界面
    this->setWindowTitle("FeiQ低配版");//设置窗体的名称
    get_IP_Address();//获取本机IP地址并显示

//初始化数据库
    my_client.sqlite_init();//初始化数据库,为聊天用户建立一个在线用户表单

//控件动作响应
    connect(Login_u,SIGNAL(send_data(QString)),this,SLOT(slot_recv(QString)));//登陆窗体动作响应

    connect(ui->listWidget_onlineuser_list,SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(slot_select_user(QListWidgetItem*)));//双击用户列表动作响应

    Login_u->show();//显示登陆界面
}

MainWindow::~MainWindow()//析构函数
{
    qDebug()<<"退出聊天程序";
    QString mess="exit:"+username_local+":"+IP_Addr;
    QByteArray message;
    QDataStream out(&message,QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_7);
    out<<mess;
    qDebug() << "退出信息:" << mess;
    Socket_login->write(message);
    qDebug()<<"消息已发出!";
    delete ui;
}

void MainWindow::slot_recv(QString res)//核对登陆信息并控制窗体切换
{
    QStringList analysis=res.split(":");
    Img=QImage(":/bk_Main.png");
    Server_IP=analysis.at(1);
    QString Port_server=analysis.at(2);

    Socket_login=new QTcpSocket(this);
    Socket_login->abort();
    //qDebug()<<"服务器IP地址:"<<Server_IP<<"端口号:"<<Port_server.toInt();
    Socket_login->connectToHost(Server_IP,Port_server.toInt());//连接到服务器,connectToHost函数为虚函数,无返回值
    connect(Socket_login,SIGNAL(readyRead()),this,SLOT(slot_recv_Message()));//数据读取响应连接到读取函数

    if(!Socket_login->waitForConnected(10000))
    {
        QMessageBox::warning(Login_u,"网络连接错误","未连接到网络,请稍后重试!",QMessageBox::Ok,QMessageBox::Cancel);
    }
    else
    {

        this->show();
        //设置用户头像(label控件)
        Login_u->close();//关闭登陆界面
        ui->label_show_username->setText(analysis.at(0));
        username_local=analysis.at(0);

        QString string="user:"+username_local+":"+IP_Addr;//拼接消息为格式:user:uesrname:IPAddr
        QByteArray message;
        QDataStream out(&message,QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_5_7);
        out<<string;
        Socket_login->write(message);


    }
}

void MainWindow::slot_select_user(QListWidgetItem *src)//双击用户名弹出聊天界面
{
    QString temp=src->text();//获取当前双击用户的名字
    QString *IP_temp=my_client.sqlite_search_IP(temp);
    int ID=my_client.sqlite_search_id(temp);//在数据库中查找对应的ID号
    if(-1 != ID)
    {
        Chart_u[ID].setWindowTitle("和"+temp+"聊天中");//依据ID号建立一个子窗口
        Chart_u[ID].setIP_min(IP_Addr+";"+*IP_temp);//显示聊天界面上的IP地址
        Chart_u[ID].set_names_client(username_local+":"+temp);//传送聊天双方的名字到聊天窗口
        Chart_u[ID].show();//显示子窗体
        Chart_u[ID].set_Socket_local(Socket_login);//传送文件描述符,以便窗体发送消息
    }
    else
    {
        qDebug()<<"ID号查询失败,请检查数据库文件!!";
    }
}

void MainWindow::get_IP_Address()//获取本机IP地址并解析IPV4地址(源自网络)
{
    QHostInfo info = QHostInfo::fromName(QHostInfo::localHostName());//首先获取本机名称,其次依据本机名称获的本机IP地址
    info.addresses();//QHostInfo的address函数获取本机ip地址
    //存在多条ip地址ipv4和ipv6:
    foreach(QHostAddress address,info.addresses())//该语句为从集合中每个成员中进行筛选:for each member进行遍历
    {
            if(address.protocol()==QAbstractSocket::IPv4Protocol)//只取ipv4协议的地址
            {
                ui->label_showIPAddr->setText(address.toString());
                IP_Addr=address.toString();
            }
    }
    //qDebug()<<"IPv4地址:"<<IP_Addr;
}

void MainWindow::paintEvent(QPaintEvent *event)//绘制背景
{
    QPainter pt(this);  //定义一个在当前窗口画画的画家
    QImage drawing = Img.scaled(this->width(),this->height());
    pt.drawImage(0,0,drawing,0,0,this->width(),this->height());
    update();
}

void MainWindow::slot_recv_Message()//接受数据响应函数
{
    QDataStream in(Socket_login);//定义数据流
    in.setVersion(QDataStream::Qt_5_7);//规定QT网络版本
    QString recv_Message;
    in >> recv_Message;
    if(recv_Message.isEmpty())
    {
         QMessageBox::warning(this,"警告","网络错误,请检查网络连接!",QMessageBox::Ok,QMessageBox::Cancel);//如果,没有接收到信息,则网络出错,没有数据
    }
    else
        network_server(recv_Message);//接受到信息,则进入字符分解程序
}

void  MainWindow::network_server(QString src)//网络服务函数
{
    QMap<QString,int> map;//以QMap形式将字符串与整型一一对应
    map.insert("user",0);//接受到用户列表信息
    map.insert("message",1);//接收到消息
    map.insert("file",2);//接收到除音乐、图片、视频外的文件

//由于多媒体文件可以预览,因此将其与其他文件分开,同时压缩文件也应该与其他的分开,以下功能以后再实现
    map.insert("video",3);//接收到视频文件
    map.insert("picture",4);//接收到图片文件
    map.insert("music",5);//接收到音乐文件
    map.insert("ZIP",6);//接收到压缩包文件
    map.insert("DIR",7);//接收到带有目录的文件

    map.insert("",888);//无数据时的错误码

    QStringList info = src.split(":");//收到的字符串以“:”为分割标志对其进行分解,并存入字符数组(列表)中,以便后期使用
//user:kk;mm;:192.168.132.108;192.168.1.140;      传输用户列表
//message:username:Hello There!  传输消息
//file:username:filename  传输文件
    //qDebug() << "类型:" << info[0]<< "  对方姓名" << info[1]<< "  内容:" << info[2];

    switch(map[info.at(0)])
    {
    case 0:
        refresh_userinfo(info.at(1)+":"+info.at(2));//刷新用户列表信息(依据服务器发送信息刷新,无需本地定时)
        break;
//接收到服务器转发的消息,消息类型:message:username:Hello There!!
    case 1:
        qDebug()<<"接收到服务器的消息:"<<info;
        splite_message(info.at(1)+":"+info.at(2));//将接收的消息继续拼合分发下去,让子函数继续解析字符串
        break;
    case 2:
        qDebug()<<"此功能待开发";
        break;
    case 3:
        qDebug()<<"此功能待开发";
        break;
    case 4:
        qDebug()<<"此功能待开发";
        break;
    case 5:
        qDebug()<<"此功能待开发";
        break;
    case 6:
        qDebug()<<"此功能待开发";
        break;
    case 7:
        qDebug()<<"此功能待开发";
        break;

    case 888:
        qDebug()<<"接收数据出错,请检查!!";

    default:
        break;
    }
}

void MainWindow::refresh_userinfo(QString src)//刷新用户列表信息
{
    QStringList source=src.split(":");//将名字和IP分开
    if("" != source.at(0) && ""!=source.at(1))
    {
        QString names=source.at(0);//获取所有在线用户的名字
        QString IPs=source.at(1);//获取所有在线用户对应的IP地址(名字与IP对应,与服务端约定名字、IP分开且对应)
        QStringList name_dis=names.split(";");//依据符号";"来区分不同用户名
        QStringList IP_dis=IPs.split(";");//分割IP地址
        if(""!=name_dis.at(0)&&""!=IP_dis.at(0)&&name_dis.length()>=1&&IP_dis.length()>=1)
        {
            QString name_client;//临时变量存放用户名
            QIcon user_list_logo(":/user_list.png");
             ui->listWidget_onlineuser_list->clear();//清除之前的用户列表
            for(int i=0;i<name_dis.length();i++)//将名字显示在列表中,将用户列表放在数据库文件中
            {
                my_client.sqlite_insert(i,name_dis.at(i),IP_dis.at(i));//将获取的用户信息加入数据库(i即为其ID,多个Dialog中传输消息依靠ID来区分)
                name_client=name_dis.at(i);//获取名称
                if(""!=name_dis.at(i))
                {
                    QListWidgetItem *temp_list = new QListWidgetItem(user_list_logo,name_client);//合成list元素
                    ui->listWidget_onlineuser_list->addItem(temp_list);//加入列表显示
                }
            }
        }
    }
    //qDebug()<<"在线用户信息刷新完成!!";
}

void  MainWindow::splite_message(QString src)//将从服务器接受的消息依据接收用户名分发到各自的窗口上
{

    qDebug()<<"分发消息服务函数:"<<src;
    QStringList analysis=src.split(":");//拆分字符串
    QString username=analysis.at(0);//解析收发双方
    QStringList user_aim=username.split("|");//分解字符串,取出收发双方姓名
    int ID=my_client.sqlite_search_id(user_aim.at(0));//分解后第一个字符串为聊天对象,查找到对方的ID号,用ID来识别窗口
    if(-1 == ID)
        qDebug()<<"ID号查询失败,无法继续分发消息,请检查!!";
    else
    {
        qDebug()<<"查询的ID号为:"<<ID;
        Chart_u[ID].show_message(user_aim.at(0)+":"+analysis.at(1));//发送消息到子窗体上
    }
}

H文件的实现:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QWidget>
//主窗体用户列表使用
#include<QListWidgetItem>

#include"my_chart.h"//添加聊天窗体类
#include"my_login.h"//添加登陆窗体类
//添加网络类
#include <QHostAddress>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QProcess>
//创建套接字使用
#include<QTcpServer>
#include<QTcpSocket>
//解析字符串使用
#include<QStringList>
//绘制背景图片以及头像使用
#include<QImage>
#include<QPainter>
#include<QPixmap>

#include<QMessageBox>
#include<QMap>

#include"server_sqlite.h"//自定义sqlite控制类

namespace Ui {
class MainWindow;
}

class MainWindow : public QWidget
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    void get_IP_Address();
    void paintEvent(QPaintEvent *event);
    void network_server(QString src);//用于分析字符串并作出相应的响应
    void refresh_userinfo(QString src);//该函数用于刷新在线用户信息
    void splite_message(QString src);//将从服务器接受的消息依据接收用户名分发到各自的窗口上(由于可以同时和多人聊天,故该部分很必要)
    ~MainWindow();
private slots:
    void slot_recv(QString res);
    void slot_select_user(QListWidgetItem *src);
    void slot_recv_Message();
private:
    Ui::MainWindow *ui;
    server_sqlite my_client;//定义一个数据库对象
    int user_count,current_user;//用于记录用户数量和当前打开窗口数
    QTcpSocket *Socket_login;//用于登陆和聊天的文件描述符
    My_Login *Login_u=new My_Login;//登录界面对象,仅显示一个
    My_Chart Chart_u[10];//聊天界面子窗口(最多打开10个)
    QString IP_Addr;//本机IP地址
    QString Server_IP;//服务器IP地址
    QImage Img;//背景图片
    QPicture *pix;//图像图片
    QString username_local;
};

#endif // MAINWINDOW_H

main.c实现

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    //w.show();

    return a.exec();
}

UI界面过多,参考图片吧!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值