QT网盘项目-DAY4-用户功能(查找用户、在线用户)

本文未经授权,禁止转载

Day3回顾-登录注册功能

        在Day3中,我们完成了以下功能 

        1、为了实现登陆注册功能,在数据库中添加了用户信息表等,并在QT中连接了数据库

        2、完成了登录与注册的功能

        3、完成了客户端下线的处理

        Day4要完成的内容

        1、完成好友界面和文件界面的设计

        2、完成查找用户的功能

        3、完成显示在线用户的功能

一、UI界面设计

        在用户完成登陆后,就应该跳转到首页进行后续操作,因此我们需要完成首页以及其他界面的UI界面设计。

         在客户端项目中创建 Qt 设计师界面类Index、 Friend、File,分别对应首页、好友界面、文件界面

        1、选择项目文件 --- > 右键 ----> add New 

        2、选择Qt ---》 Qt 设计师界面类  

        3、选择 Widget 类

        4、 输入类名,注意路径

5、注意项目路径,别添加到其他项目中

Friend和File的添加同Index一致

1.1 好友界面设计

  添加完成之后,就会发现,项目中多了这几个文件。

        1、 点击friend.ui 进入 好友界面

        (1)添加5个按钮(QPushButton),并按照不同的按钮功能进行命名

        (2)添加一个列表框(QListWidget),命名为 friend_LW

 2、进行排版

         其中、列表框(QListWidget)的QFrame中的frameShape属性设置为NoFrame(无边框属性)

        剩余的UI美化请自行搜索,按照自己喜好来就行,重点是功能实现

1.2 文件界面设计

        1、点击 file.ui 进入文件界面

        (1)添加一个列表框(QListWidget),命名为file_LW

        (2)添加10个按钮(QListWidget),根据按钮功能进行命名

        2、UI设计不做详细讲述

1.3 首页设计

        1、点击 index.ui 进入首页界面

        (1)添加两个按钮(QListWidget),分别是好友和文件,用来切换界面

        (2)添加一个窗口控件(QStackedWidget),用来展示不同的界面

        2、将好友界面(friend.ui)和文件界面(file.ui)绑定在QStackedWidget上

        (1)选中QStackedWidget,右键 ---》 提升为

        (2)输入类名,将其提升为窗口,

                分别将Friend和File添加到QStackedWidget中。

        

                 然后改一下两个页面的名字。

1.4 界面跳转

        上面我们完成了首页,文件界面、好友界面的UI设计。

        我们的本意是,在首页点击好友按钮,QStackedWidget切换到好友界面,点击文件按钮,切换到文件界面。

        因此我们需要在 两个按钮的槽函数中,设置界面跳转。(通过按钮转到槽函数)

        1、好友按钮的槽函数

// 首页点击好友按钮,切换到好友页面
void Index::on_friend_PB_clicked()
{
    // 设置切换界面--好友界面
    ui->stackedWidget->setCurrentIndex(0);
    // 设置按钮样式
    ui->friend_PB->setStyleSheet("QPushButton{padding:25px;background-color: rgb(255, 255, 255);}");
    ui->file_PB->setStyleSheet("QPushButton{padding:25px;background-color: rgba(255, 255, 255,0);}");
}

        2、文化按钮的槽函数

// 首页点击文件按钮,切换到文件页面
void Index::on_file_PB_clicked()
{
    // 设置切换的界面--文件界面
    ui->stackedWidget->setCurrentIndex(1);
    // 设置按钮的样式
    ui->file_PB->setStyleSheet("QPushButton{padding:25px;background-color: rgb(255, 255, 255);}");
    ui->friend_PB->setStyleSheet("QPushButton{padding:25px;background-color: rgba(255, 255, 255,0);}");
}

 1.5 实现单例模式

       1、实现单例模式

        我们在登录界面Client中,将Client类的对象实现了单例模式,目的是为了每个客户端只能实例化一个登录界面。

        而每个客户端也只能展示一个首页,因此也要实现单例模式。

        (1)构造函数私有化、删除拷贝构造和赋值运算符重载。

        index.h

private:
    explicit Index(QWidget *parent = nullptr);
    Index(const Index& instance) = delete;
    Index operator=(const Index&) = delete;

        (2)定义静态的成员函数getInstance(),返回一个静态引用的对象。

Index &Index::getInstance()
{
    static Index instance;
    return instance;
}

        2、定义获取好友界面和文件界面的公有函数

        我们将Index类实现单例模式之后,就没有办法获取到好友界面和文件界面中的一些控件了,因此我们需要在lndex中,添加获取好友界面和文件界面的公有函数。这样就可以通过这个公有函数来获取某个界面中的控件。

        index.cpp 

// 获取好友界面
Friend* Index::getFriend()
{
    return ui->friendPage;
}
// 获取文件界面
File *Index::getFile()
{
    return ui->filePage;
}

1.6 登录后跳转到首页

        Day3中,我们完成了登录注册的功能,在登录成功后,我们就需要隐藏登录界面,并跳转到首页。

        因此,我们需要在接收消息的函数中,在接收到成功登录的响应之后,将登录界面隐藏,并显示首页。

client.cpp    Client::recvMsg()

        // 登录响应
        case ENUM_MSG_TYPE_LOGIN_RESPOND:
        {
            // 将消息取出
            bool ret;
            char caName[32] = {'\0'};
            memcpy(&ret,pdu->caData,sizeof(bool));
            memcpy(caName,pdu->caData+32,32);
            // 根据返回的响应进行处理
            if(ret)
            {
                // 登录成功,用成员变量记录登录成功的用户名
                m_LoginName = caName;
                qDebug()<<"recvMsg LOGIN_REQUEST m_userName"<<m_LoginName;
                QMessageBox::information(this,"登录","登录成功");

                // 登录成功后,跳转到首页
                Index::getInstance().show();
                // 隐藏登录界面
                hide();
            }
            else
            {   // 登录失败,提示登录失败
                QMessageBox::information(this,"登录","登录失败:用户名或密码非法");
            }
            break;
        }

二、查找用户

        通过上面的内容,我们就完成了首页、好友界面、文件界面的设计,以及登录后的界面跳转。接下来,我们就开始正式的完成功能了。下面要完成的是好友界面的查找用户功能。

2.1 查找用户的流程

        下面我们来分析一下,查找用户具体有那些流程?

         在好友界面点击查找用户的按钮,弹出一个输入框,输入要查找的用户名,将用户名发送给服务器,服务器在用户信息表中查找并返回结果。

  • 客户端点击查找用户,发送查找请求(将输入框的用户名发送给服务器)
    • 用户点击查找用户,弹出输入框,输入要查找的用户名
    • 从输入框中取出用户名
    • 构建自定义消息结构体对象pdu(不使用柔性数组(caMsg),使用固定长度的数组(caData[64]))因此在初始化PDU时,传入0即可。
    • 在PDU协议中的添加对应功能的请求和响应消息类型
      • 在消息类型的枚举值中,添加查找用户的请求和响应
    • 在pdu填入消息类型和要发送的数据(用户名)
    • 发送 pdu到服务器
  • 服务器接收、处理并响应查找用户请求(在用户表中查找用户名)
    • 需要数据库操作,在数据库操作类中,添加处理查找用户的函数
      • 根据用户名判断用户是否已存在(利用select查找用户名)
      • 用户存在,返回查找成功;用户不存在,返回不存在
    • 在服务器的接收消息的函数中,处理消息类型为查找用户请求的情况。
    • 取出 pdu 中的数据,调用处理函数,将取出的数据传给处理数据库操作类中处理查找用户的函数。
    • 得到处理查找用户的函数的返回值,得到处理结果
    • 构建发给客户端的响应 pdu,消息类型为 查找用户响应
    • 将处理结果放入响应 pdu。
    • 将响应 pdu 发送给客户端。
  • 客户端接收查找用户响应并显示结果
    • 客户端的接收消息函数中,根据消息类型进行处理,进入查找用户响应的处理阶段
    • 将结果显示给用户

2.2 客户端发送查找用户请求

  • 客户端点击查找用户,发送查找请求(将输入框的用户名发送给服务器)
    • 用户点击查找用户,弹出输入框,输入要查找的用户名
    • 从输入框中取出用户名
    • 构建自定义消息结构体对象pdu(不使用柔性数组(caMsg),使用固定长度的数组(caData[64]))因此在初始化PDU时,传入0即可。
    • 在PDU协议中的添加对应功能的请求和响应消息类型
      • 在消息类型的枚举值中,添加查找用户的请求和响应
    • 在pdu填入消息类型和要发送的数据(用户名)
    • 发送 pdu到服务器

         fiend.cpp ---- Friend::on_findUser_PB_clicked()

        1、在friend.ui界面中,选择查找用户的按钮,跳转到槽函数

        2、在槽函数中,弹出一个输入框(QInputDialog),输入框的返回值就是要查找的用户名

// 输入框 获取 要查找的用户名
QString strName = QInputDialog::getText(this,"查找用户","用户名:");

        3、检查输入内容的合法性

    if(strName.isEmpty())
    {   // 判断输入内容是否为空
        QMessageBox::critical(this,"输入错误","用户名不能为空");
        return;
    }
    if(strName.toStdString().size() > 32)
    {   // 判断输入内容长度
        QMessageBox::critical(this,"输入错误","用户名长度应小于32位");
        return;
    }
    if(strName==Client::getInstance().getLoginName())
    {   // 判断要查找的用户是否是自己
        QMessageBox::critical(this,"提示","查找的竟然是你自己!");
        return;
    }

         4、构建消息pdu,传入要查找的用户名,并发送给服务器

        需要在消息协议的消息类型枚举值中,添加两个枚举值,分别是查找用户的请求和查找用户的响应。 

        protocol.h 

    ENUM_MSG_TYPE_FIND_USER_REQUEST, // 查找用户的请求
    ENUM_MSG_TYPE_FIND_USER_RESPOND, // 查找用户的响应

        fiend.cpp ---- Friend::on_findUser_PB_clicked()

    // 构建PDU对象
    PDU* pdu = initPDU(0);
    // 传入消息类型
    pdu->uiMsgType = ENUM_MSG_TYPE_FIND_USER_REQUEST;
    // 存放用户名
    memcpy(pdu->caData,strName.toStdString().c_str(),strName.toStdString().size());

    // 发送消息,应该是socket对象调用write函数
    Client::getInstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);

    // 释放pdu
    free(pdu);
    pdu = NULL;

2.3 服务器处理查找用户请求

  • 服务器接收、处理并响应查找用户请求(在用户表中查找用户名)
    • 需要数据库操作,在数据库操作类中,添加处理查找用户的函数
      • 根据用户名判断用户是否已存在(利用select查找用户名)
      • 用户存在,返回查找成功;用户不存在,返回不存在
    • 在服务器的接收消息的函数中,处理消息类型为查找用户请求的情况。
    • 取出 pdu 中的数据,调用处理函数,将取出的数据传给处理数据库操作类中处理查找用户的函数。
    • 得到处理查找用户的函数的返回值,得到处理结果
    • 构建发给客户端的响应 pdu,消息类型为 查找用户响应
    • 将处理结果放入响应 pdu。
    • 将响应 pdu 发送给客户端。

        1、在数据库操作类中,添加处理查找用户的函数

        (1)在数据库操作类中定义处理查找用户的函数,需要接收一个参数,就是要查找的用户名

int handleFindUser(const char *name)

        (2)利用sql语句,在用户信息表中,查找用户名,并输出在线状态

select online from user_info where name = 'name'

        (3)返回查找结果,查找过程出错返回-2,没找到该用户,返回-1,找到了,返回在线状态

 operatedb.cpp

// 处理查找用户的函数
int OperateDB::handleFindUser(const char *name)
{
    if(name==NULL)
    {
        return -2; // 空指针 返回-2
    }
    // 判断用户是否存在,输出在线状态
    QString sql = QString("select online from user_info where name = '%1'").arg(name);
    // 创建一个 QSqlQuery 对象,用来执行 sql语句
    QSqlQuery q;
    if(!q.exec(sql))
    {
        return -2; // 执行错误,返回-2
    }
    if(q.next())
    {   //查找到内容,返回在线状态,需要获取的值为字符串类型,得转换为整型
        return q.value(0).toInt();
    }
    else
    {
        // 没查到内容,用户不存在
        return -1; // 用户不存在
    }
}

        2、 在服务器接收消息的函数中,处理消息类型为查找用户请求的情况

        mytcpsocket.cpp -- MyTcpSocket::recvMsg() 

        case ENUM_MSG_TYPE_FIND_USER_REQUEST:

        (1)将要查找的用户名从pdu中取出,调用数据库操作类中,处理查找用户的函数,得到返回值。

    // 将消息取出
    char caName[32] = {'\0'};
    memcpy(caName,pdu->caData,32);
    // 测试
    qDebug()<<"recvMsg FIND_USER caName: "<<caName;

    // 处理消息
    int ret = OperateDB::getInstance().handleFindUser(caName);

         (2)构建响应pdu,将得到的返回值存到响应pdu中,并发送到客户端

    // 向客户端发送响应
    // 初始化响应注册的PDU对象
    PDU* findUserPdu = initPDU(0);
    // 消息类型为注册响应
    findUserPdu->uiMsgType = ENUM_MSG_TYPE_FIND_USER_RESPOND;
    // 将消息存储到消息结构体
    memcpy(findUserPdu->caData,&ret,sizeof(int));
    // 利用socket 向客户端发送 注册的响应
    write((char*)findUserPdu,findUserPdu->uiPDULen);

 2.4 客户端接收查找用户响应

        在客户端接收消息的函数中,根据消息类型,处理消息类型为查找用户响应的情况。

        1、将消息从pdu中取出

    // 将消息取出
    int ret;
    memcpy(&ret,pdu->caData,sizeof(int));

         2、根据返回值,作出不同的响应

        (1)返回值为 -2:查找时出现内部错误

        (2)返回值为 -1:没查到该用户

        (3)返回值为 0 :该用户不在线

        (4)返回值为 1 :该用户在线

// 根据返回的响应进行处理
if(ret == -1)
{
    QMessageBox::information(&Index::getInstance(),"查找用户","该用户不存在");
    return;
}
else if(ret == 0)
{
    QMessageBox::information(&Index::getInstance(),"查找用户","该用户不在线");
    return;
}
else if(ret == 1)
{
    QMessageBox::information(&Index::getInstance(),"查找用户","该用户在线");
    return;
}
else
{
    QMessageBox::critical(&Index::getInstance(),"查找用户","查找错误");
    return;
}

2.5 功能展示

        到这里,我们就完成了查找用户的功能。

        当然,你也可以在服务器发回响应时,返回要查找的用户名,在客户端根据不同的响应作出提示的时候,显示你查找的用户名。

三、显示在线用户

3.1 显示在线用户的流程

下面我们来分析一下,显示在线用户具体有那些流程?

         在好友界面点击查找用户的按钮,客户端向服务器发送在线用户请求,服务器查找在线的用户,并将结果返回。客户端显示结果。

        需要新建一个界面来显示所有的在线用户。

  • 客户端点击查找用户,发送在线用户请求(发送请求给服务器)
    • UI界面:创建一个设计师界面类(OnlineUser),界面中添加一个 列表框(QListWidget)控件来展示所有的在线用户。
    • 用户点击在线用户按钮,发送显示在线用户的请求。
    • 构建自定义消息结构体对象pdu,不用传输实际消息,只需要传输请求的类型,因此传入0即可。
    • 在PDU协议中的添加对应功能的请求和响应消息类型
      • 在消息类型的枚举值中,添加在线用户的请求和响应
    • 在pdu填入消息类型,且没有要发送的数据。
    • 发送 pdu到服务器
  • 服务器接收、处理并响应在线用户请求(在用户表中查找在线用户)
    • 需要数据库操作,在数据库操作类中,添加处理在线用户的函数
      • 根据online字段,获取在线用户的用户名
      • 用户在线,将所有在线的用户名存储在QStringList列表中,并返回字符串列表
    • 在服务器的接收消息的函数中,处理消息类型为在线用户请求的情况。
    • 调用得到数据库操作类中处理在线用户的函数,得到的返回值,QStringList
    • 构建发给客户端的响应 pdu,消息类型为 在线用户响应
      • 根据所有在线用户的用户名列表(QStringList)获取用户名的个数
      • 根据个数计算出caMsgLen(实际消息的长度) = 个数 ✖ 32
    • 遍历QStringList,挨个将在线用户的用户名放入响应 pdu。
    • 将响应 pdu 发送给客户端。
  • 客户端接收查找用户响应并显示结果
    • 在OnlineUser中,定义一个显示在线用户的函数(showOnlineUser()),将QStringList中的用户名放在 列表框(QListWidget)中。
    • 客户端的接收消息函数中,根据消息类型进行处理,进入在线用户响应的处理阶段
    • 将pdu中的用户名挨个取出,存储在QStringList中(不包括自己),并调用showOnlineUser()函数传入QStringList

3.2 UI设计

1、添加一个设计师界面类OnlineUser(参考 第一章)

        UI界面:创建一个设计师界面类(OnlineUser),界面中添加一个 列表框(QListWidget)控件来展示所有的在线用户。

        添加完成后,点击onlineuser.ui,进入界面,添加QListWidget控件,并修改控件的名字。

2、在OnlineUser类的构造函数中,添加关闭选项

         在onlineuser的构造函数中,添加setAttribute(Qt::WA_QuitOnClose,false);

        目的是为了在主窗口关闭时,该窗口也跟着关闭。

 onlineuser.cpp

OnlineUser::OnlineUser(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::OnlineUser)
{
    ui->setupUi(this);
    // 主窗口关闭,在线用户窗口也会跟着关闭
    setAttribute(Qt::WA_QuitOnClose,false);
}

3、在friend类中,添加一个 OnlineUser类的成员变量

        创建该成员变量的目的是,为了调用OnlineUser中的控件以及调用属于OnlineUser类的成员函数。

        在friend的构造函数中,new一个新的OnlineUser,赋值给该成员变量。

        在friend的析构函数中,释放该成员变量。

 friend.cpp

Friend::Friend(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Friend)
{
    ui->setupUi(this);
    // 新建一个 OnlineUser 对象,用于展示在线用户的界面
    m_onlineUser = new OnlineUser;
}

Friend::~Friend()
{
    if(!m_onlineUser) delete m_onlineUser;
    delete ui;
}

3.3 客户端发送在线用户请求

  • 客户端点击查找用户,发送在线用户请求(发送请求给服务器)
    • 用户点击在线用户按钮,发送显示在线用户的请求。
    • 构建自定义消息结构体对象pdu,不用传输实际消息,只需要传输请求的类型,因此传入0即可。
    • 在PDU协议中的添加对应功能的请求和响应消息类型
      • 在消息类型的枚举值中,添加在线用户的请求和响应
    • 在pdu填入消息类型,且没有要发送的数据。
    • 发送 pdu到服务器

1、在线用户按钮的点击槽函数中,发送在线用户请求

friend.cpp  --- Friend::on_onlineUser_PB_clicked()

(1)如果在线用户界面(onlineuser)是隐藏的,则进行显示

    // 如果该界面是隐藏的,则进行展示
    if(m_onlineUser->isHidden())
    {
       m_onlineUser->show();
    }

(2)在消息协议的消息类型枚举值中,添加在线用户请求和响应

    ENUM_MSG_TYPE_ONLINE_USER_REQUEST, // 在线用户的请求
    ENUM_MSG_TYPE_ONLINE_USER_RESPOND, // 在线用户的响应

(3)构建pdu并发送给服务器

    // 构建pdu
    PDU* pdu = initPDU(0);
    // 传入消息类型
    pdu->uiMsgType = ENUM_MSG_TYPE_ONLINE_USER_REQUEST;
    // 发送pdu到服务器
    Client::getInstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);
    // 释放pdu
    free(pdu);
    pdu = NULL;

3.4 服务器处理在线用户请求

  • 服务器接收、处理并响应在线用户请求(在用户表中查找在线用户)
    • 需要数据库操作,在数据库操作类中,添加处理在线用户的函数
      • 根据online字段,获取在线用户的用户名
      • 用户在线,将所有在线的用户名存储在QStringList列表中,并返回字符串列表
    • 在服务器的接收消息的函数中,处理消息类型为在线用户请求的情况。
    • 调用得到数据库操作类中处理在线用户的函数,得到的返回值,QStringList
    • 构建发给客户端的响应 pdu,消息类型为 在线用户响应
      • 根据所有在线用户的用户名列表(QStringList)获取用户名的个数
      • 根据个数计算出caMsgLen(实际消息的长度) = 个数 ✖ 32
    • 遍历QStringList,挨个将在线用户的用户名放入响应 pdu。
    • 将响应 pdu 发送给客户端。

1、在数据库操作类中,定义处理在线用户的函数 (handleOnlineUser

        (1)在用户信息表中,根据online字段,得到所有在线用户的用户名

select name from user_info where online = 1

        (2)将所有在线的用户名挨个取出,存储到QStringList列表中,并返回该列表

operatedb.cpp

 // 处理在线用户的函数
QStringList OperateDB::handleOnlineUser()
{
    // 判断用户是否在线,输出用户名
    QString sql = QString("select name from user_info where online = 1");
    // 创建一个 QSqlQuery 对象,用来执行 sql语句
    QSqlQuery q;
    q.exec(sql);

    QStringList nameList;
    while(q.next())
    {
        // 测试--打印从数据库取到的每一条用户名
        // qDebug()<<"handleOnlineUser "<<q.value(0).toString();
        // 将在线的用户名添加到列表中
        nameList.append(q.value(0).toString());
    }
    return nameList;

}

2、在服务器接收消息的函数中,处理消息类型为在线用户请求的情况

        (1)调用数据库操作类中,处理查找用户的函数,得到返回值QStringList(所有在线用户的用户名)

// 处理消息
QStringList nameList = OperateDB::getInstance().handleOnlineUser();

        (2)计算caMsgLen的长度。

        实际消息的长度 = 列表元素个数 ✖ 32(每个用户名的最大长度)

// 获取列表大小
int listSize = nameList.size();
// 计算实际消息的长度
uint uiMsgLen = listSize*32;

        (3)构建响应pdu,将在线用户的用户名挨个存储在响应pdu中

// 初始化响应在线用户的PDU对象
PDU* onlineUserPdu = initPDU(uiMsgLen);
// 消息类型为在线用户响应
onlineUserPdu->uiMsgType = ENUM_MSG_TYPE_ONLINE_USER_RESPOND;
// 将用户名 挨个放到 caMsg中
for(int i = 0; i<listSize; i++)
{
    // 测试
    // qDebug()<<"ONLINE_USER_REQUEST " << nameList.at(i);

    // 将每一个用户名都存储到 caMsg中
    memcpy(onlineUserPdu->caMsg+i*32,nameList.at(i).toStdString().c_str(),32);
}

         (4)将响应pdu 发送给客户端

// 利用socket 向客户端发送 在线用户的响应
write((char*)onlineUserPdu,onlineUserPdu->uiPDULen);

// 释放 onlineUserPdu
free(onlineUserPdu);
onlineUserPdu=NULL;

3.5 客户端接收在线用户响应

  • 客户端接收查找用户响应并显示结果
    • 在OnlineUser中,定义一个显示在线用户的函数(showOnlineUser()),将QStringList中的用户名放在 列表框(QListWidget)中。
    • 客户端的接收消息函数中,根据消息类型进行处理,进入在线用户响应的处理阶段
    • 将pdu中的用户名挨个取出,存储在QStringList中(不包括自己),并调用showOnlineUser()函数传入QStringList

1、在OnlineUser类中,定义一个显示在线用户的函数(showOnlineUser())

        传入一个QStringList 字符串列表,将该列表中的每一个元素挨个显示到列表框中

onlineuser.cpp

// 展示在线用户
void OnlineUser::showOnlineUser(QStringList nameList)
{
    ui->onlineUser_LW->clear();
    ui->onlineUser_LW->addItems(nameList);

}

2、在接收消息函数中,根据消息类型,处理消息类型为在线用户响应的情况

        (1)挨个取出响应pdu中的用户名,并存放在一个QStringList 中。

        先通过实际消息长度,计算用户的个数

        再通过循环,挨个取出用户名(不包括自己)

// 获取在线用户的个数
uint listSize = pdu->uiMsgLen/32;
qDebug()<<"listSize  "<<listSize;
// 创建变量存储在线用户的用户名
char userName[32];
QStringList nameList;
// 将caMsg中的用户名挨个取出,并放到nameList中
for(uint i = 0; i <listSize; i++)
{
    // 挨个取出用户名
    memcpy(userName,pdu->caMsg+i*32,32);
    // 测试
    // qDebug()<<"ONLINE_USER_RESPOND  "<<QString(userName);
    // 跳过自己
    if(QString(userName) == m_LoginName)
    {
        continue;
    }
    // 将取到的用户名存放到 nameList中
    nameList.append(QString(userName));
}

        (2)调用OnlineUser中,定义的显示在线用户的函数(showOnlineUser()),并将QStringList 传入

// 调用展示在线用户的函数
Index::getInstance().getFriend()->m_onlineUser->showOnlineUser(nameList);

3.6 功能展示

        到这里,我们就完成了在线用户的功能。

        当然,你也可以在服务器在数据拷表中查找数据时,就将自己的用户名排除在外,这样在使用socket传输数据时,就可以节省32字节的大小。

        这里,登录了4个客户端。

总结

实现的内容

        1、完成了首页、好友界面、文件界面的UI界面设计

        2、完成了好友界面的添加用户功能、显示在线用户功能

注意:

        再次声明本文未经授权,禁止转载

        1、对于UI界面的设计,请自行完成美化。

        2、对于控件的名称,一定要按照控件的功能进行命名,否则后面调用控件的时候,你自己都不知道这是什么控件。

        3、如果你发现了文章中的问题,勿喷!!请私信我,我会改正。(十分感谢)

完整代码

    代码量增加,把所有代码复制粘贴到CSDN是不现实的,想要源码的话,就自己去历史提交里找吧。下面这几次提交。

NetdiskProject: QT网盘项目的实现。 - Gitee.com

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值