侧边导航栏是网页或应用程序界面的一种常见布局,它通常位于页面或应用程序的侧边位置,用来展示导航菜单或功能链接,方便用户快速访问不同的页面或功能。
侧边导航栏一般具有以下特点:
-
布局紧凑:侧边导航栏通常采用垂直布局,将导航菜单以列表或图标的形式展示在侧边栏上,占用较小的页面空间。
-
导航菜单:侧边导航栏主要用于展示导航菜单,可以将不同的页面或功能按照层级结构排列,以便用户快速找到目标页面。
-
展开和收起:对于较大型的导航菜单,侧边导航栏通常支持展开和收起功能,用户可以通过点击菜单项或折叠按钮来展开或收起子菜单,以节省页面空间。
-
高亮当前页面:侧边导航栏通常会在当前页面的菜单项上应用一种视觉样式,如高亮或加粗显示,以帮助用户快速定位当前页面。
-
响应式设计:随着移动设备的普及,侧边导航栏在响应式设计中扮演重要角色,可以根据屏幕尺寸自动调整布局和样式,以提供更好的用户体验。
一、简述
在Qt中,可以通过继承QWidget类来实现自定义侧边导航栏。在paintEvent()函数中绘制自定义的导航栏样式。可以使用QPainter类的绘图功能来实现。为了实现与用户的交互,可以重写鼠标事件的处理函数,例如mouseMoveEvent()和mousePressEvent()。
二、 设计思路
- 创建一个新的类QNavigationWidget,继承自QWidget类。在这个类中,我们可以添加需要的功能和样式
- 重写paintEvent()函数,绘制自定义的导航栏样式。使用QPainter类的绘图功能来实现。
- 重写鼠标事件的处理函数,mouseMoveEvent()和mousePressEvent(),实现与用户的交互。
- 通过判断鼠标的位置来确定用户是否点击了导航栏上导航项,发出相应的信号
三、效果
四、核心代码
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 ¤t){
tipsLabel->setText("Item: " + QString::number(current));
});
}
MainWindow::~MainWindow()
{
}
侧边导航栏可以为用户提供方便快捷的导航方式,使用户能够更轻松地浏览和使用网页或应用程序的各个功能和内容。在设计侧边导航栏时,需要考虑页面结构、用户需求和界面美感等因素,以提供更好的使用体验。
谢谢您的关注和阅读。如果您还有其他问题或需要进一步的帮助,请随时联系我。祝您一切顺利!
六、源代码下载