利用Qt写的局域网聊天工具(服务端)

一、局域网聊天工具

有FeiQ大佬坐镇,也只是写着玩玩

软件运行截图:

 

文件:服务端运行时会在D盘产生一个数据库文件:D:\\user_info_server.db

二、源码:

sqlite部分源码:

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("D:\\user_info_server.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地址(字符串形式)
{
    if(!sqlite_is_Exist(name_t,IP_t))//返回值为false,需要对其进行修改
    {
        name_t+="1";//修改用户名,避免转发消息出错(识别方面需要进一步debug)
    }

    temp.clear();
    temp.sprintf("insert into user values(%d,'%s','%s','online')",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();//返回当前用户的ID号
     }
     return -1;
 }

 bool server_sqlite::sqlite_is_Empty()//判断数据库是否为空
 {
     QString temp="";
     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;
     if("" != temp)
     {
         return false;
     }
     else
     {
         return true;
     }
 }

bool server_sqlite::sqlite_is_Exist(QString name_se,QString IP_se)
{
    int ID=sqlite_search_id(name_se);//查找名字对应的ID号,如果返回值不为-1则代表该用户存在
    if(-1 == ID)//该用户名称不存在
    {
        return true;//直接将该用户信息插入,实现同一主机多个用户
    }
    else//用该用户名存在
    {
//查找用户名对应的IP地址
        temp.clear();
        temp.sprintf("select IP from user where id = '%d'",ID);//SQL语句查找IP地址
        QSqlQuery search;
        if(!search.exec(temp))
        {
            qDebug()<<"表单查询IP失败,请检查!!";
            return false;
        }
        if(search.first())
        {
           if(IP_se==search.value(0).toString())
           {
               qDebug()<<"用户名已存在,且IP地址相同";
               sqlite_update(name_se,"online");//设置该用户在线
               return true;
           }
           else
           {
               qDebug()<<"用户名存在,但是IP地址不同,将重新设置名称!!";
               return false;//表示需要修改用户名后再进行插入
           }
        }
    }
    return false;
}

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);//查找指定用户数据
    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对象,以达到准确转发消息
    bool sqlite_is_Empty();//判断当前数据库是否为空
    bool sqlite_is_Exist(QString name_se, QString IP_se);//判断当前用户是否已经存在,存在则仅修改其在线状态,否则将插入到数据库中,作为新加成员
     ~server_sqlite()
    {
        my_db.close();
    }
};
#endif

图形界面代码实现:

cpp代码:

#include "widget.h"
#include "ui_widget.h"
#include"server_sqlite.h"//自定义sqlite服务

#include <QPainter>
#include <QPixmap>

#include<QTime>//时间
#include<QDate>//日期
#include<QDataStream>//数据流
#include<QByteArray>//字节数组

#include<QMap>//将字符串和整型匹配

server_sqlite server;//定义一个服务数据库对象(主函数中也用这个对象)

Widget::Widget(QWidget *parent) :QWidget(parent),
ui(new Ui::Widget)
{
    ui->setupUi(this);
//显示时间:
    QString temp1=QTime::currentTime().toString();
    QString temp2=QDate::currentDate().toString("yyyy年MM月dd日  ");
    QString show=temp2+" "+temp1;
    ui->local_Time->setText(show);
//定时器
    this->startTimer(1000);//用于刷新时间的定时器,ID=1
    this->startTimer(3000);//间隔3秒刷新用户在线信息,ID=2
//固定窗体大小
    this->setFixedSize(523,454);//窗口大小固定
    state=true;//标识服务状态,true表明服务已打开
    countor=0;//数据库用户数量计数
    ui->textEdit_showuseringo->setReadOnly(true);//设为只读
    ui->textEdit_showuser_cominication->setReadOnly(true);//设为只读
    connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(slot_net_server()));//打开、关闭按钮动作连接
}

Widget::~Widget()
{
    server.sqlite_delete_all();
    server.sqlite_delete_table();//退出时删除所有数据库文件
    qDebug()<<"退出服务器程序!!";
    delete ui;
}
//设置背景图案
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter (this);
    painter.drawPixmap(0,0,this->width(), this->height(),QPixmap(":/blue.jpg"));
}

void Widget::slot_net_server()//按钮响应函数,用于打开网络或关闭网络
{
    if(state)//按钮切换及功能实现
    {
        state=false;
        ui->pushButton->setText("关闭服务");
        get_IP_Address();//获取本机IP地址并显示在label控件中
        Server_t=new QTcpServer(this);//创建服务器
        Socket_t=new QTcpSocket(this);//创建socket
        Socket_List=new QList<QTcpSocket*>;//创建socket文件描述符集合
        Server_t->listen(QHostAddress::Any,8080);//接收来自任意网卡的信息
        connect(Server_t,SIGNAL(newConnection()),this,SLOT(slot_new_connect()));//将新链接连接到槽函数响应
        ui->label_show_message->setText("服务已打开!");
    }
    else
    {
        state=true;
        ui->pushButton->setText("打开服务");

        Server_t->close();
        for(int i=0;i<Socket_List->length();i++)//关闭服务,关闭所有Socket
        {
            Socket_List->at(i)->close();
        }
        ui->label_show_message->setText("服务已关闭!!");
        ui->local_IP_2->clear();
        ui->textEdit_showuser_cominication->clear();
        ui->textEdit_showuseringo->clear();
    }
}

void Widget::get_IP_Address()//获取本机IP地址并解析IPV4地址(源自网络)
{
    QString temp;
    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->local_IP_2->setText("IP:"+address.toString()+"  Port: 8080");
                temp=address.toString();
            }
    }
    qDebug()<<"IPv4地址:"<<temp;
}

void Widget::timerEvent(QTimerEvent *event)
{
    //qDebug()<<"当前定时器ID:"<<event->timerId();
    if(1 == event->timerId())//定时器ID为1时(1s溢出),刷新时间
    {
        QString temp1=QTime::currentTime().toString();
        QString temp2=QDate::currentDate().toString("yyyy年MM月dd日  ");
        QString show=temp2+" "+temp1;
        ui->local_Time->setText(show);
        display_userinfo();
    }
    else if(2 == event->timerId() && 0 != countor)//如果刷新用户列表的定时器溢出,则发送用户列表给所有的用户
    {
        ui->label_show_message->clear();
        if(0 == Socket_List->length())
        {
            qDebug()<<"当前没有用户,不需要刷新用户列表";
        }
        else
        {
            QString user_info;
            QString user_name;
            QString user_IP;
            user_info=*server.sqlite_online_server();//获取在线用户信息
            if(""!=user_info)//有在线用户信息则进行分发
            {
                QStringList analysis=user_info.split("\n");//分解字符串
                for(int i=0;i<countor;i++)//所有用户数量,包含不在线,以此为界限拼接在线用户信息并发送,刷新用户列表
                {
                    if(""!=analysis.at(i))
                    {
                        user_info.clear();//清楚缓存
                        user_info=analysis.at(i);//取得单一用户的所有信息
                        QStringList analy_temp=user_info.split(":");//分解字符串
                        user_name+=analy_temp.at(0)+";";//将用户名都合并到user_name
                        user_IP+=analy_temp.at(1)+";";//将用户IP地址合并到user_IP
                    }
                }
                user_info.clear();//清除缓存
                user_info="user:"+user_name+":"+user_IP;//拼接用户信息为格式:user:user1;user2;user3;:IP1;IP2;IP3;

                for(int i=0;i<Socket_List->length();i++)//遍历发送数据(每个用户都要刷新在线列表)
                {
                    QByteArray message;
                    QDataStream out(&message,QIODevice::WriteOnly);
                    out.setVersion(QDataStream::Qt_5_7);
                    out<<user_info;
                    Socket_List->at(i)->write(message);//从网络发送用户列表(所有在线用户都会接收到消息)
                }
            }
        }
    }
    else
         ui->label_show_message->setText("等待用户连接!");
}

void Widget::slot_new_connect()
{
    Socket_t=Server_t->nextPendingConnection();//建立套接字
    Socket_List->append(Socket_t);//加入到描述符集合
    id_src=Socket_List->length();//取得当前描述符集合最大数值,作为数据库插入的ID (最大数值依据连接用户改变)

    connect(Socket_t,SIGNAL(readyRead()),this,SLOT(slot_readMesssage()));//将所有的socket都连接到slot_readMessage(),而后再遍历取出数据
}

void Widget::slot_readMesssage()//该函数在任意一个描述符出现readyread信号后均能进入,因此需要遍历描述符集合
{
    QString recv;
    qDebug()<<"接收到信息,正在遍历服务器文件描述符集合查找信息";
    for(int i=0;i<Socket_List->length();i++)//遍历Socket_List中所有的描述符,若其没有数据,则跳过,直到找到数据
    {
        QDataStream in(Socket_List->at(i));
        in.setVersion(QDataStream::Qt_5_7);//定义版本,以免出错
        in>>recv;
        if(!(recv.isEmpty()))//若取得的数据不为空,说明是该描述符发出的readyread信号
        {
            String_Splitor(recv);//将接收到的字符串进行解析并进入下一步操作
        }
    }
}

 void Widget::send_Message(QString user_src,QString message_src)//该成员函数仅用于发送消息
 {
     QByteArray message;//临时byte数组
     QDataStream out(&message,QIODevice::WriteOnly);//数据流向
     out.setVersion(QDataStream::Qt_5_7);//指定QT版本,以免网络传输出错
     out<<message_src;//将要发送的消息导入流

     int des=server.sqlite_search_id(user_src);//依据用户表单查找接收方注册ID号

     Socket_List->at(des-1)->write(message);//发送信息,Socket_List列表中位置与其长度相差1,从0开始,des为数据库查询得到的ID号,其为Socket_List的length()返回值
 }

void Widget::String_Splitor(QString src)
{
    QStringList analysis=src.split(":");
    qDebug()<<"字符解析结果:"<<analysis;

//分析客户端发送来的字符串第一个单词:message->发送消息,user->注册服务,file->发送文件,video->发送视频(switch不支持字符分支)
    QMap<QString,int> map;//利用Map容器将字符串与整形数字对应,可以高效使用switch语句
//匹配字符与整型,等价于 if("user"==analysis.at(0))
                                                                 //int index=0;
    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("exit",666);//退出客户端发送的下线消息

    map.insert("",888);

    switch(map[analysis.at(0)])//查找键值取出对应的整型数
    {
    case 0://user:username:192.168.1.168
      {
        qDebug()<<"进入分支user";
        QString name_m=analysis.at(1);
        QString IP_m=analysis.at(2);//取出新加入用户的名字和IP地址

        QString show_in;//用于在UI上显示某人加入聊天队列的信息
        show_in.sprintf("用户%s加入聊天队列,IP为:%s",name_m.toStdString().data(),IP_m.toStdString().data());
        ui->textEdit_showuser_cominication->append(show_in);//将新连接的用户追加显示在左侧textEdit上

        ui->label_show_message->setText("有新用户连接!");//提示有新用户连接进来
        qDebug()<<"正在插入数据库";
        server.sqlite_insert(id_src,name_m,IP_m);//新用户的信息插入到数据库文件中
        qDebug()<<"插入数据库完成";
        countor++;
        qDebug()<<show_in;
        break;
      }
    case 1://message:user1|user2:"hello there!!"
      {
        QString name_m=analysis.at(1);//取出双方姓名user1|user2:user1给user2发送消息
        QStringList name_send_recv=name_m.split("|");//分离发送接收方信息
        QString message_m=analysis.at(2);//取出所发送的信息
        QString *state_line=server.sqlite_search(name_send_recv.at(1));
        if("offline" == *state_line)
            send_Message(name_send_recv.at(1),"message:"+name_send_recv.at(0)+"|"+name_send_recv.at(1)+":对方不在线,请稍后重试!");
        else
            send_Message(name_send_recv.at(1),"message:"+name_send_recv.at(0)+"|"+name_send_recv.at(1)+":"+message_m);//发送数据到指定的socketID接收方
        //qDebug()<<"消息已发出,接收方名字:"<<name_m;
        ui->textEdit_showuser_cominication->append(name_m+message_m);
        break;
     }
    case 2://file:user1|user2:filename.size
        break;
    case 3://video:user1|user2:filename.size
        break;
    case 4://picture:user1|user2:filename.size
        break;
    case 5://music:user1|user2:filename.size
        break;
    case 6://zip:user1|user2:filename.size
        break;
    case 7://dir:user1|user2:filename.size
        break;
    case 666://exit:username:192.168.1.168
    {
        QString name_m=analysis.at(1);//取出退出用户名
        server.sqlite_update(name_m,"offline");//更新在线状态
        QString show_in;//用于在UI上显示某人加入聊天队列的信息
        show_in.sprintf("用户%s下线",name_m.toStdString().data());//拼接字符串
        ui->textEdit_showuser_cominication->append(show_in);//将下线的用户追加显示在左侧textEdit上
    }
        break;
    case 888://内部错误
        qDebug()<<"字符串解析出错!!";
        break;
    default:
        qDebug()<<"指令解析出错,检查网络接收数据!!";
        break;
    }

}

void Widget::display_userinfo()
{
    QString *user_online=server.sqlite_online_server();
    QString *user_offline=server.sqlite_offline_server();
    if(0!=countor&&state)
    {
        ui->textEdit_showuseringo->clear();

        ui->textEdit_showuseringo->append("当前在线用户:\n");
        ui->textEdit_showuseringo->append(*user_online);
        ui->textEdit_showuseringo->append("离线用户:\n");
        ui->textEdit_showuseringo->append(*user_offline);
    }
}

H文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
//添加网络类
#include <QHostAddress>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QProcess>
#include <QMainWindow>
#include<QTcpServer>
#include<QTcpSocket>
#include<QList>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    void timerEvent(QTimerEvent *event);//重写定时器虚函数,依据ID号区分功能
    void get_IP_Address();//获取本机IP地址
    void send_Message(QString user_src,QString message_src);//发送消息到客户端
    void String_Splitor(QString src);//分解字符串实现不同的功能
    void paintEvent(QPaintEvent *event);
    void display_userinfo();
    ~Widget();

private slots:
    void slot_new_connect();//新的连接
    void slot_readMesssage();//接收消息
    void slot_net_server();//网络服务函数

private:
    Ui::Widget *ui;
    QTcpSocket *Socket_t;//用于发送接收数据
    QTcpServer *Server_t;//用于连接
    QList<QTcpSocket*> *Socket_List;//用于将socket集合
    bool state;//当前状态
    int id_src;//数据库ID号索引(有bug)
    int countor;//记录用户数量
};

#endif // WIDGET_H

main.c文件

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

#include "server_sqlite.h" //自定义数据库操作文件


extern server_sqlite server;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;

    if(!server.sqlite_init())//初始化一个数据对象
    {
        qDebug()<<"数据表单已存在,请检查!!"<<endl;
    }

    w.show();
    return a.exec();
}

UI界面的xml代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>523</width>
    <height>454</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QLabel" name="local_Time">
   <property name="geometry">
    <rect>
     <x>270</x>
     <y>410</y>
     <width>241</width>
     <height>31</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>楷体</family>
     <pointsize>13</pointsize>
    </font>
   </property>
   <property name="frameShape">
    <enum>QFrame::Panel</enum>
   </property>
   <property name="frameShadow">
    <enum>QFrame::Raised</enum>
   </property>
   <property name="text">
    <string/>
   </property>
  </widget>
  <widget class="QLabel" name="local_IP_2">
   <property name="geometry">
    <rect>
     <x>270</x>
     <y>60</y>
     <width>241</width>
     <height>31</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>楷体</family>
     <pointsize>12</pointsize>
    </font>
   </property>
   <property name="frameShape">
    <enum>QFrame::Panel</enum>
   </property>
   <property name="frameShadow">
    <enum>QFrame::Raised</enum>
   </property>
   <property name="text">
    <string/>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>410</x>
     <y>10</y>
     <width>101</width>
     <height>41</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>楷体</family>
     <pointsize>13</pointsize>
    </font>
   </property>
   <property name="text">
    <string>打开服务</string>
   </property>
  </widget>
  <widget class="QLabel" name="label_2">
   <property name="geometry">
    <rect>
     <x>50</x>
     <y>30</y>
     <width>171</width>
     <height>21</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>楷体</family>
     <pointsize>13</pointsize>
    </font>
   </property>
   <property name="text">
    <string>用户交互信息详情</string>
   </property>
  </widget>
  <widget class="QLabel" name="label_3">
   <property name="geometry">
    <rect>
     <x>320</x>
     <y>120</y>
     <width>171</width>
     <height>21</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>楷体</family>
     <pointsize>13</pointsize>
    </font>
   </property>
   <property name="text">
    <string>用户连接情况</string>
   </property>
  </widget>
  <widget class="QLabel" name="label_4">
   <property name="geometry">
    <rect>
     <x>270</x>
     <y>30</y>
     <width>131</width>
     <height>21</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>楷体</family>
     <pointsize>13</pointsize>
    </font>
   </property>
   <property name="text">
    <string>服务IP地址</string>
   </property>
  </widget>
  <widget class="QLabel" name="label_show_message">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>420</y>
     <width>251</width>
     <height>21</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>楷体</family>
     <pointsize>11</pointsize>
    </font>
   </property>
   <property name="text">
    <string/>
   </property>
  </widget>
  <widget class="QTextEdit" name="textEdit_showuseringo">
   <property name="geometry">
    <rect>
     <x>270</x>
     <y>150</y>
     <width>241</width>
     <height>251</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>楷体</family>
     <pointsize>11</pointsize>
    </font>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color: qlineargradient(spread:pad, x1:0.523, y1:0.00586364, x2:0.471, y2:1, stop:0 rgba(155, 250, 205, 75), stop:1 rgba(255, 255, 255, 255));</string>
   </property>
  </widget>
  <widget class="QTextEdit" name="textEdit_showuser_cominication">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>60</y>
     <width>241</width>
     <height>341</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>楷体</family>
     <pointsize>11</pointsize>
    </font>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color: qlineargradient(spread:pad, x1:0.523, y1:0.00586364, x2:0.471, y2:1, stop:0 rgba(155, 250, 205, 75), stop:1 rgba(255, 255, 255, 255));</string>
   </property>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

       以上代码没有完成文件传输等功能,由于涉及到压缩算法和网络优化,暂时没有算法能力实现,故搁置了,后面算法能力提升后将对该部分进行补充升级。

      不足之处多多指点,多谢。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值