QT实现自定义侧边导航栏

news2025/2/6 7:42:10

        侧边导航栏是网页或应用程序界面的一种常见布局,它通常位于页面或应用程序的侧边位置,用来展示导航菜单或功能链接,方便用户快速访问不同的页面或功能。

侧边导航栏一般具有以下特点:

  1. 布局紧凑:侧边导航栏通常采用垂直布局,将导航菜单以列表或图标的形式展示在侧边栏上,占用较小的页面空间。

  2. 导航菜单:侧边导航栏主要用于展示导航菜单,可以将不同的页面或功能按照层级结构排列,以便用户快速找到目标页面。

  3. 展开和收起:对于较大型的导航菜单,侧边导航栏通常支持展开和收起功能,用户可以通过点击菜单项或折叠按钮来展开或收起子菜单,以节省页面空间。

  4. 高亮当前页面:侧边导航栏通常会在当前页面的菜单项上应用一种视觉样式,如高亮或加粗显示,以帮助用户快速定位当前页面。

  5. 响应式设计:随着移动设备的普及,侧边导航栏在响应式设计中扮演重要角色,可以根据屏幕尺寸自动调整布局和样式,以提供更好的用户体验。

 一、简述

         在Qt中,可以通过继承QWidget类来实现自定义侧边导航栏。在paintEvent()函数中绘制自定义的导航栏样式。可以使用QPainter类的绘图功能来实现。为了实现与用户的交互,可以重写鼠标事件的处理函数,例如mouseMoveEvent()和mousePressEvent()。

二、 设计思路    
  1. 创建一个新的类QNavigationWidget,继承自QWidget类。在这个类中,我们可以添加需要的功能和样式
  2. 重写paintEvent()函数,绘制自定义的导航栏样式。使用QPainter类的绘图功能来实现。
  3. 重写鼠标事件的处理函数,mouseMoveEvent()和mousePressEvent(),实现与用户的交互。
  4. 通过判断鼠标的位置来确定用户是否点击了导航栏上导航项,发出相应的信号
三、效果 

 

四、核心代码  
1、头文件

       qnavigationwidget.h

#ifndef QNAVIGATIONWIDGET_H
#define QNAVIGATIONWIDGET_H

#include <QWidget>
#include <QMouseEvent>

class QNavigationWidget : public QWidget
{
    Q_OBJECT
    
public:
    QNavigationWidget(QWidget *parent=0);
    ~QNavigationWidget();

    void addItem(const QString &iconPath,const QString &title);
    void setWidth(const int &width);
    void setBackgroundColor(const QColor &color);
    void setSelectColor(const QColor &color);
    void setMouseInColor(const QColor &color);
    void setRowHeight(const int &height);

protected:
    void paintEvent(QPaintEvent *);
    void mouseMoveEvent(QMouseEvent *);
    void mousePressEvent(QMouseEvent *);
    void leaveEvent(QEvent *);

private:
    QList<QString> listIcons;
    QList<QString> listItems;
    QColor backgroundColor;
    QColor selectedColor;
    QColor mouseInColor;
    int rowHeight;
    int currentIndex;
    int mouseMoveIndex;

signals:
    void currentItemChanged(const int &index);
};

#endif
2、实现代码

qnavigationwidget.cpp

#include "qnavigationwidget.h"
#include <QPainter>
#include <QDebug>

QNavigationWidget::QNavigationWidget(QWidget *parent) : QWidget(parent)
{
    backgroundColor = "#E4E4E4";
    selectedColor = "#2CA7F8";
    mouseInColor = "#C4C4C4";
    rowHeight = 40;
    currentIndex = 0;
    mouseMoveIndex = -1;

    setMouseTracking(true);
    setFixedWidth(120);
}

QNavigationWidget::~QNavigationWidget()
{
}

void QNavigationWidget::addItem(const QString &iconPath,const QString &title)
{
    listIcons << iconPath;
    listItems << title;

    update();
}

void QNavigationWidget::setWidth(const int &width)
{
    setFixedWidth(width);
}

void QNavigationWidget::setBackgroundColor(const QColor &color)
{
    backgroundColor = color;

    update();
}

void QNavigationWidget::setSelectColor(const QColor &color)
{
    selectedColor = color;

    update();
}

void QNavigationWidget::setMouseInColor(const QColor &color)
{
    mouseInColor = color;

    update();
}

void QNavigationWidget::setRowHeight(const int &height)
{
    rowHeight = height;

    update();
}

void QNavigationWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    // Draw background color.
    painter.setPen(Qt::NoPen);
    painter.setBrush(backgroundColor);
    painter.drawRect(rect());

    // Draw Items
    int count = 0;
    for (const QString &str : listItems)
    {
        QPainterPath itemPath;
        itemPath.addRect(QRect(0, count * rowHeight, width(), rowHeight));

        if (currentIndex == count)
        {
            painter.setPen("#FFFFFF");
            painter.fillPath(itemPath, selectedColor);
        }
        else if(mouseMoveIndex == count)
        {
            painter.setPen("#FFFFFF");
            painter.fillPath(itemPath, mouseInColor);
        }
        else
        {
            painter.setPen("#202020");
            painter.fillPath(itemPath, backgroundColor);
        }

        //painter.drawText(QRect(40, count * rowHeight, width()-40, rowHeight), Qt::AlignVCenter | Qt::AlignHCenter, str);
        painter.drawPixmap(QRect(20, (count * rowHeight+(rowHeight-20)/2), 20, 20),QPixmap(listIcons[count]));
        painter.drawText(QRect(45, count * rowHeight, width()-40, rowHeight), Qt::AlignVCenter, str);

        ++count;
    }
}

void QNavigationWidget::mouseMoveEvent(QMouseEvent *e)
{
    if (e->y() / rowHeight < listItems.count())
    {
        mouseMoveIndex = e->y() / rowHeight;
    }
    else
    {
        mouseMoveIndex = -1;
    }

    update();
}

void QNavigationWidget::mousePressEvent(QMouseEvent *e)
{
    if (e->y() / rowHeight < listItems.count())
    {
        currentIndex = e->y() / rowHeight;
        emit currentItemChanged(currentIndex);
        update();
    }
}

void QNavigationWidget::leaveEvent(QEvent *)
{
    if(mouseMoveIndex !=-1 )
    {
        mouseMoveIndex = -1;
        update();
    }
}
五、使用示例

以下是一个简单的示例代码,演示了如何在Qt中使用此控件:

#include "mainwindow.h"
#include <QHBoxLayout>
#include <QLabel>
#include "qnavigationwidget.h"

MainWindow::MainWindow(QMainWindow *parent) : QMainWindow(parent)
{
    resize(600, 400);

    QWidget *mainWidget = new QWidget;
    QWidget *rightWidget = new QWidget;
    QVBoxLayout *rightLayout = new QVBoxLayout(rightWidget);
    QHBoxLayout *mainLayout = new QHBoxLayout(mainWidget);
    QNavigationWidget *navigationWidget = new QNavigationWidget;
    QLabel *tipsLabel = new QLabel("Item: 0");

    navigationWidget->setRowHeight(50);
    navigationWidget->addItem(":/res/contents.png","常规");
    navigationWidget->addItem(":/res/editclear.png","消息");
    navigationWidget->addItem(":/res/editcopy.png","字幕");
    navigationWidget->addItem(":/res/filenew.png","下载");
    navigationWidget->addItem(":/res/fileopen.png","会员");
    navigationWidget->addItem(":/res/filesave.png","关于");

    rightLayout->addWidget(tipsLabel, 0, Qt::AlignCenter);
    
    mainLayout->setContentsMargins(0, 0, 0, 0);
    mainLayout->addWidget(navigationWidget);
    mainLayout->addWidget(rightWidget);
    
    setCentralWidget(mainWidget);

    connect(navigationWidget, &QNavigationWidget::currentItemChanged, this, [=](const int &current){
        tipsLabel->setText("Item: " + QString::number(current));
    });
}

MainWindow::~MainWindow()
{
}

        侧边导航栏可以为用户提供方便快捷的导航方式,使用户能够更轻松地浏览和使用网页或应用程序的各个功能和内容。在设计侧边导航栏时,需要考虑页面结构、用户需求和界面美感等因素,以提供更好的使用体验。

        谢谢您的关注和阅读。如果您还有其他问题或需要进一步的帮助,请随时联系我。祝您一切顺利!

六、源代码下载

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2056510.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实用工具:[TrafficMonitor]任务栏电脑性能监控安装指南

实用工具&#xff1a;[TrafficMonitor]任务栏电脑性能监控安装指南 效果图 话不多说&#xff0c;直接上软件效果图&#xff1a; 内容介绍 支持监控的指标&#xff1a; 上传下载CPU利用率内存利用率CPU温度总网速CPU频率显卡利用率显卡温度硬盘温度主板温度硬盘利用率 一共…

三千元左右的卧室投影仪怎么选?当贝D6X Pro代替电视的最佳选择

想象一下&#xff0c;在舒适的卧室中&#xff0c;只需轻轻一瞥&#xff0c;便能享受一场视觉盛宴&#xff0c;无需起身&#xff0c;天花板即成为你的私人影院。这一梦想现已成真&#xff0c;只需挑选一台合适的卧室投影仪&#xff0c;即可实现这一愿望。 下面是2024年卧室投影仪…

DLL修复工具哪个好用?分享电脑丢失dll文件一键修复方法,快速修复!

电脑丢失dll文件一键修复都有哪些方法&#xff1f;想必很多小伙伴都对dll文件了解颇少&#xff0c;不过电脑倒是出现过很多次关于dll文件丢失的问题。本文就和大家分享一下dll文件是什么&#xff1f;如果电脑出现dll文件缺失的情况应该如何修复&#xff0c;一起来学习下吧&…

llama3 结构详解

文章目录 1. Llama3 整体结构2. 模块详解2.1 模块1: Embeddings2.2 模块2: RoPE2.3 模块3: Transformer Block2.4 模块4: RMSNorm2.5 模块5: Attention2.6 模块6: ADD2.7 模块7: FFN2.8 模块8: Linear 1. Llama3 整体结构 llama3 的整体结构还是延续transformer decoder 架构&a…

【计算机组成原理】二、数据的表示和运算:1.数值与编码(十进制二进制转换、BCD码、ASCII码、汉字编码、奇偶校验码、循环冗余检测CRC、海明码)

二、数据的表示和运算 文章目录 二、数据的表示和运算1.数值与编码1.1数据存储和排列❗1.2十进制转换1.2.1整数1.2.2小数 1.3二进制转换1.3.1 B->O1.3.2 B->H 1.4真值&机器数1.5 BCD码1.6 ASCII码1.7汉字与GBK1.8 UTF1.9检错码1.9.1奇偶校验码1.9.2循环冗余检测CRC1.…

鸿蒙Harmony实战:常用命令交互工具—“hvigorw”

hvigor通过hvigorw工具&#xff0c;实现命令行交互。 命令行使用方式 hvigorw [taskNames...] <options> 常用命令 查询 选项 说明 -h, --help 打印hvigor的命令帮助信息。 -v, --version 打印hvigor版本信息。 编译构建 选项 说明 clean 清理构建产物buil…

启动团队活力:5款互动游戏助力新人快速融入

在加入新团队时&#xff0c;很多人都会感到尴尬和不适应。作为团队的领导者&#xff0c;帮助新成员顺利融入团队是至关重要的。组织一场“破冰游戏”是一个有效的策略&#xff0c;不仅可以活跃团队气氛&#xff0c;还能促进成员之间的交流和理解。这时候&#xff0c;团队的领导…

ReFT: reasoning with reinforced Fine-Tuning

从一个question中看到多种多样的cot&#xff0c;都可以从中学习。 offline self-training 数据的质量是模型自己来定义的。 思考增加或者减少一条数据&#xff0c;对于模型训练的影响。 用influence function来衡量新增一条数据对于模型训练的整体的影响。 高质量的数据能够…

深度学习Day-30:CGAN入门丨生成手势图像丨可控制生成

&#x1f368; 本文为&#xff1a;[&#x1f517;365天深度学习训练营] 中的学习记录博客 &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制] 要求&#xff1a; 结合代码进一步了解CGAN学习如何运用生成好的生成器生成指定图像 一、 基础配置 语言环境&#x…

功能测试与自动化测试详解

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 什么是自动化测试? 自动化测试是指利用软件测试工具自动实现全部或部分测试&#xff0c;它是软件测试的一个重要组成 部分&#xff0c;能完成许多手工测试无法实…

【C++】————智能指针

作者主页&#xff1a; 作者主页 本篇博客专栏&#xff1a;C 创作时间 &#xff1a;2024年8月20日 一&#xff0c;什么是智能指针 在C中没有垃圾回收机制&#xff0c;必须自己释放分配的内存&#xff0c;否则就会造成内存泄露。解决这个问题最有效的方法是使用智能指针&…

传染病防控宣传小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;防控知识管理&#xff0c;医院信息管理&#xff0c;健康上报管理&#xff0c;医疗捐赠管理&#xff0c;捐赠信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首…

力扣面试经典算法150题:买卖股票的最佳时机 II

买卖股票的最佳时机 II 今天的题目是力扣面试经典150题中的数组的中等难度题&#xff1a;买卖股票的最佳时机 II。 题目链接&#xff1a;https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/?envTypestudy-plan-v2&envIdtop-interview-150 问…

EfficientFormer 系列算法

1. EfficientFormer V1 模型 论文地址&#xff1a;https://proceedings.neurips.cc/paper_files/paper/2022/file/5452ad8ee6ea6e7dc41db1cbd31ba0b8-Paper-Conference.pdf EfficientFormer V1 基于 ViT 的模型中使用的网络架构和具体的算子&#xff0c;找到端侧低效的原因。然…

深入剖析资产负债率与净资产收益率,掌握财务报表解读技巧

一、概述 财务报表中蕴含了丰富的信息&#xff0c;如果我们在解读时没有清晰的思路&#xff0c;忽略重点&#xff0c;就很容易被庞杂的数据搞得晕头转向。本文将从几个关键指标出发&#xff0c;包括资产负债率的分析、净资产收益率的解读&#xff0c;以及如何计算销售复合增长…

企业高性能web服务器——nginx

一、web基础介绍 Apache 和 Nginx 是当今为互联网提供动力的最流行的Web 服务器。 1.1、apache服务器 1.1.1、Apache prefork 模型 预派生模式&#xff0c;有一个主控制进程&#xff0c;然后生成多个子进程&#xff0c;使用select模型&#xff0c;最大并发1024每个子进程有一…

萌啦数据ozon怎么用,萌啦数据ozon使用教程

在跨境电商的浩瀚蓝海中&#xff0c;Ozon作为俄罗斯及独联体地区领先的电商平台&#xff0c;正吸引着越来越多中国卖家的目光。而“萌啦数据”作为专为跨境电商卖家打造的数据分析工具&#xff0c;其针对Ozon平台的功能更是让众多商家如虎添翼。今天&#xff0c;我们就来详细探…

后悔和父母出游的年轻人,正在计划带宠物旅行

文 | 螳螂观察 作者 | 青月 美编 |赵倩 相比于和父母一起出门远游&#xff0c;现在越来越多的95后“铲屎官”似乎更愿意和自家的宠物们组“旅游搭子”。 这听起来可能有些刺耳&#xff0c;但其实是当下很多年轻人的心声。 “带父母一起去北京玩&#xff0c;本来打算第二天…

【 每日一题 | 计算机网络】定长子网划分

重要知识点讲解 我们首先需要了解一下无分类CIDR的编址格式x.x.x/24&#xff0c;表示有24位的网路号&#xff0c;那么相应的主机号为32-248位子网掩码&#xff08;很重要&#xff09;&#xff0c;用来表示IP地址中标识网络号以及子网号的&#xff0c;也就是说如果要进行子网划…

鸿蒙内核源码分析(中断切换篇) | 系统因中断活力四射

关于中断部分系列篇将用三篇详细说明整个过程. 中断概念篇 中断概念很多&#xff0c;比如中断控制器&#xff0c;中断源&#xff0c;中断向量&#xff0c;中断共享&#xff0c;中断处理程序等等.本篇做一次整理.先了解透概念才好理解中断过程.用海公公打比方说明白中断各个概念…