首页 > 编程语言 >C++全栈聊天项目(20) 聊天列表动态加载

C++全栈聊天项目(20) 聊天列表动态加载

时间:2024-06-08 11:33:23浏览次数:14  
标签:hover 20 C++ state 聊天 设置 press font border

聊天列表动态加载

如果要动态加载聊天列表内容,我们可以在列表的滚动区域捕获鼠标滑轮事件,并且在滚动到底部的时候我们发送一个加载聊天用户的信号

bool ChatUserList::eventFilter(QObject *watched, QEvent *event)
{
    // 检查事件是否是鼠标悬浮进入或离开
    if (watched == this->viewport()) {
        if (event->type() == QEvent::Enter) {
            // 鼠标悬浮,显示滚动条
            this->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        } else if (event->type() == QEvent::Leave) {
            // 鼠标离开,隐藏滚动条
            this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        }
    }

    // 检查事件是否是鼠标滚轮事件
    if (watched == this->viewport() && event->type() == QEvent::Wheel) {
        QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
        int numDegrees = wheelEvent->angleDelta().y() / 8;
        int numSteps = numDegrees / 15; // 计算滚动步数

        // 设置滚动幅度
        this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() - numSteps);

        // 检查是否滚动到底部
        QScrollBar *scrollBar = this->verticalScrollBar();
        int maxScrollValue = scrollBar->maximum();
        int currentValue = scrollBar->value();
        //int pageSize = 10; // 每页加载的联系人数量

        if (maxScrollValue - currentValue <= 0) {
            // 滚动到底部,加载新的联系人
            qDebug()<<"load more chat user";
            //发送信号通知聊天界面加载更多聊天内容
            emit sig_loading_chat_user();
         }

        return true; // 停止事件传递
    }

    return QListWidget::eventFilter(watched, event);
}

回到ChatDialog类里添加槽函数

void ChatDialog::slot_loading_chat_user()
{
    if(_b_loading){
        return;
    }

    _b_loading = true;
    LoadingDlg *loadingDialog = new LoadingDlg(this);
    loadingDialog->setModal(true);
    loadingDialog->show();
    qDebug() << "add new data to list.....";
    addChatUserList();
    // 加载完成后关闭对话框
    loadingDialog->deleteLater();

    _b_loading = false;
}

槽函数中我们添加了LoadingDlg类,这个类也是个QT 设计师界面类,ui如下

https://cdn.llfc.club/1717637779912.jpg

添加stackwidget管理界面

ChatDialog界面里添加stackedWidget,然后添加两个页面

https://cdn.llfc.club/1717639561119.jpg

回头我们将这两个界面升级为我们自定义的界面

我们先添加一个自定义的QT设计师界面类ChatPage,然后将原来放在ChatDialog.ui中的chat_data_wid这个widget移动到ChatPage中ui布局如下

https://cdn.llfc.club/1717640323397.jpg

布局属性如下

https://cdn.llfc.club/1717640426705.jpg

然后我们将ChatDialog.ui中的chat_page 升级为ChatPage。

接着我们将ChatPage中的一些控件比如emo_lb, file_lb升级为ClickedLabel, receive_btn, send_btn升级为ClickedBtn

如下图:

https://cdn.llfc.club/1717644080174.jpg

然后我们在ChatPage的构造函数中添加按钮样式的编写

ChatPage::ChatPage(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ChatPage)
{
    ui->setupUi(this);
    //设置按钮样式
    ui->receive_btn->SetState("normal","hover","press");
    ui->send_btn->SetState("normal","hover","press");

    //设置图标样式
    ui->emo_lb->SetState("normal","hover","press","normal","hover","press");
    ui->file_lb->SetState("normal","hover","press","normal","hover","press");
}

因为我们继承了QWidget,我们想实现样式更新,需要重写paintEvent

void ChatPage::paintEvent(QPaintEvent *event)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

类似的,我们的ListItemBase

void ListItemBase::paintEvent(QPaintEvent *event)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

ClickedLabel完善

我们希望ClickedLabel在按下的时候显示按下状态的资源,在抬起的时候显示抬起的资源,所以修改按下事件和抬起事件

void ClickedLabel::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        if(_curstate == ClickLbState::Normal){
              qDebug()<<"clicked , change to selected hover: "<< _selected_hover;
            _curstate = ClickLbState::Selected;
            setProperty("state",_selected_press);
            repolish(this);
            update();

        }else{
               qDebug()<<"clicked , change to normal hover: "<< _normal_hover;
            _curstate = ClickLbState::Normal;
            setProperty("state",_normal_press);
            repolish(this);
            update();
        }
        return;
    }
    // 调用基类的mousePressEvent以保证正常的事件处理
    QLabel::mousePressEvent(event);
}

抬起事件

void ClickedLabel::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        if(_curstate == ClickLbState::Normal){
             // qDebug()<<"ReleaseEvent , change to normal hover: "<< _normal_hover;
            setProperty("state",_normal_hover);
            repolish(this);
            update();

        }else{
             //  qDebug()<<"ReleaseEvent , change to select hover: "<< _selected_hover;
            setProperty("state",_selected_hover);
            repolish(this);
            update();
        }
        emit clicked();
        return;
    }
    // 调用基类的mousePressEvent以保证正常的事件处理
    QLabel::mousePressEvent(event);
}

qss美化

我们添加qss美化一下

LoadingDlg{
    background: #f2eada;
}

#title_lb{
    font-family: "Microsoft YaHei";
    font-size: 18px;
    font-weight: normal;
}

#chatEdit{
    background: #ffffff;
    border: none; /* 隐藏边框 */
    font-family: "Microsoft YaHei"; /* 设置字体 */
    font-size: 18px; /* 设置字体大小 */
    padding: 5px; /* 设置内边距 */
}

#send_wid{
    background: #ffffff;
    border: none; /* 隐藏边框 */
}

#add_btn[state='normal']{
    border-image: url(:/res/add_friend_normal.png);
}

#add_btn[state='hover']{
    border-image: url(:/res/add_friend_hover.png);

}

#add_btn[state='press']{
    border-image: url(:/res/add_friend_hover.png);
}

#receive_btn[state='normal']{
   background: #f0f0f0;
   color: #2cb46e;
   font-size: 16px; /* 设置字体大小 */
   font-family: "Microsoft YaHei"; /* 设置字体 */
   border-radius: 20px; /* 设置圆角 */
}

#receive_btn[state='hover']{
   background: #d2d2d2;
   color: #2cb46e;
   font-size: 16px; /* 设置字体大小 */
   font-family: "Microsoft YaHei"; /* 设置字体 */
   border-radius: 20px; /* 设置圆角 */
}

#receive_btn[state='press']{
   background: #c6c6c6;
   color: #2cb46e;
   font-size: 16px; /* 设置字体大小 */
   font-family: "Microsoft YaHei"; /* 设置字体 */
   border-radius: 20px; /* 设置圆角 */
}

#send_btn[state='normal']{
    background: #f0f0f0;
    color: #2cb46e;
    font-size: 16px; /* 设置字体大小 */
    font-family: "Microsoft YaHei"; /* 设置字体 */
    border-radius: 20px; /* 设置圆角 */
}

#send_btn[state='hover']{
   background: #d2d2d2;
   color: #2cb46e;
   font-size: 16px; /* 设置字体大小 */
   font-family: "Microsoft YaHei"; /* 设置字体 */
   border-radius: 20px; /* 设置圆角 */
}

#send_btn[state='press']{
   background: #c6c6c6;
   color: #2cb46e;
   font-size: 16px; /* 设置字体大小 */
   font-family: "Microsoft YaHei"; /* 设置字体 */
   border-radius: 20px; /* 设置圆角 */
}

#tool_wid{
    background: #ffffff;
    border-bottom: 0.5px solid #ececec; /* 设置下边框颜色和宽度 */
}

#emo_lb[state='normal']{
    border-image: url(:/res/smile.png);
}

#emo_lb[state='hover']{
    border-image: url(:/res/smile_hover.png);
}

#emo_lb[state='press']{
    border-image: url(:/res/smile_press.png);
}

#file_lb[state='normal']{
    border-image: url(:/res/filedir.png);
}

#file_lb[state='hover']{
    border-image: url(:/res/filedir_hover.png);
}

#file_lb[state='press']{
    border-image: url(:/res/filedir_press.png);
}

效果

最后整体运行一下看看效果, 下一节我们实现红框内的内容

https://cdn.llfc.club/1717645209118.jpg

视频链接

https://www.bilibili.com/video/BV13Z421W7WA/?spm_id_from=333.788&vd_source=8be9e83424c2ed2c9b2a3ed1d01385e9

源码链接

https://gitee.com/secondtonone1/llfcchat

标签:hover,20,C++,state,聊天,设置,press,font,border
From: https://blog.csdn.net/secondtonone1/article/details/139496900

相关文章

  • C++全栈聊天项目(21) 滚动聊天布局设计
    滚动聊天布局设计我们的聊天布局如下图最外层的是一个chatview(黑色),chatview内部在添加一个MainLayout(蓝色),MainLayout内部添加一个scrollarea(红色),scrollarea内部包含一个widget(绿色),同时也包含一个HLayout(紫色)用来浮动显示滚动条。widget内部包含一个垂直布局Vlayout(黄......
  • NOIP 2015 T1 骑士的金币(coin)
    描述国王将金币作为奖励,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天)里,每天收到两枚金币;之后三天(第四、五、六天)里,每天收到三枚金币;之后四天(第七、八、九、十天)里,每天收到四枚金币……这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士......
  • NOIP 2012 T1 质因数分解
    描述已知正整数 n 是两个不同的质数的乘积,试求出较大的那个质数。输入描述输入只有一行,包含一个正整数 n。输出描述输出只有一行,包含一个正整数 p,即较大的那个质数。用例输入1 21用例输出1 7提示【数据范围】对于 60%的数据, 6≤n≤1000。 对于 1......
  • Springboot计算机毕业设计疫情蔬菜供给系统演示录像2022【附源码】开题+论文+mysql+程
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景2022年,全球仍受到新冠疫情的深远影响。在疫情期间,人们的生活方式和消费习惯发生了显著变化,尤其是在食品采购方面。蔬菜作为日常生活的必需品,其供给稳......
  • 2024年5月文章一览
    2024年5月编程人总共更新了7篇文章:1.2024年4月文章一览2.《自动机理论、语言和计算导论》阅读笔记:p215-p3513.《自动机理论、语言和计算导论》阅读笔记:p352-P4014.《自动机理论、语言和计算导论》阅读笔记:p402-p4275.《自动机理论、语言和计算导论》阅读笔记:p428-p5256.《编......
  • 「漏洞复现」锐捷校园网自助服务系统 login_judge.jsf 任意文件读取漏洞(XVE-2024-211
    0x01 免责声明请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,如有侵权请联系删除。本次测试仅供学习使用,如若非法他用,与平台和本文作者无关,需......
  • C++入门 初始化列表 & 隐式类型转换
    目录初始化列表构造函数体赋值初始化列表格式初始化列表特性每个成员变量在初始化列表中只能出现一次类中以下成员必须初始化尽量使用初始化列表初始化数组初始化 声明次序就是初始化顺序多参数初始化列表再谈隐式类型转换拷贝引用explicit关键字定义用法缺......
  • P7219 [JOISC2020] 星座 3 题解
    会发现题目的坐标其实是平面直角坐标系。我们按\(y\)坐标从小到大考虑所有的星星,假设当前考虑到了星星\(i\)。我们先计算出之前所有能够影响到\(i\)的星星的代价和为\(cost\)(可以用树状数组维护)。然后分类讨论。若\(c_i\lecost\),那么肯定直接将\(i\)直接涂黑,因为它更......
  • Pyramid Vision Transformer, PVT(ICCV 2021)原理与代码解读
    paper:PyramidVisionTransformer:AVersatileBackboneforDensePredictionwithoutConvolutionsofficialimplementation:GitHub-whai362/PVT:OfficialimplementationofPVTseries存在的问题现有的VisionTransformer(ViT)主要设计用于图像分类任务,难以直接用......
  • P10560 [ICPC2024 Xi'an I] The Last Cumulonimbus Cloud 题解
    好好玩的题。思路对于一个图上邻域问题,我们有一个很经典的做法:根号分治。考虑根号分治的本质是什么。我们把点分成两类,平衡每一种点的时间,也就是度数大的与度数小的点。所以对于这道题,我们有了更加好的做法。发现题目给的图的性质就是一个天然的划分方案。我们每次找到图中......