1、目的
最近在工作中需要实现一个Qt的侧边栏,通过按钮控制显示和隐藏,此外还要求实现自定义气泡提示框,最终参考网上知识进行了实现,效果如下:
1、窗口控件大小可以随窗体自由缩放; 2、侧边栏按钮可以控制侧边栏的显示隐藏; 3、侧边栏按钮可以控制侧边栏内容的切换; 4、实现自定义气泡提示框,提示框形状依据需求自绘; 5、鼠标悬停到按钮控件时候可以弹出自定义气泡提示框,移开时提示框消失。
完整源码下载地址:源码地址
2、侧边栏的显示与隐藏
侧边栏采用一个QWidget作为父窗口,嵌套一个QStackedWidget作为内容显示控件,侧边按钮栏中添加按钮设定按钮图片,点击“显示/隐藏”按钮控制侧边栏的显示和隐藏,同时切换按钮图片。
void MyGlobalMap::navigateButtonClick(){QPushButton* btn = (QPushButton*)sender();QString sName = btn->objectName();if (sName == "sideButton"){if (ui.sidewidget->isHidden()){ui.sidewidget->show();ui.sideButton->setIcon(QIcon(":/images/left.png"));}else{ui.sidewidget->hide();ui.sideButton->setIcon(QIcon(":/images/right.png"));}}}
3、自定义气泡消息提示框的绘制
自定义对话框的绘制主要难点在于指示小三角的绘制。本文采用一个QWidget作为父窗口,嵌套一个QWidget作为子窗口,其中在初始化中对子窗口QWidget进行重绘,加入指引小箭头。
实现代码:
#pragma once#include <QWidget>#include "ui_TransferlistWidget.h"const int TRIANGLE_WIDTH = 10;// 小三角的宽度;const int TRIANGLE_HEIGHT = 30; // 小三角的高度;const int BORDER_RADIUS = 15;// 窗口边角的弧度;class TransferlistWidget : public QWidget{Q_OBJECTpublic:TransferlistWidget(QWidget *parent = nullptr);~TransferlistWidget();// 小三角相对于控件的位置enum Derection {left,right,up,down};// 设置小三角偏移量void setStartPos(int nOffset);// 设置小三角宽和高;void setTriangleInfo(int width, int height);// 设置小三角的位置void setDerection(Derection d);// 重载move函数,(x,y)是气泡窗口小三角的坐标void myMove(QPoint point);protected:void paintEvent(QPaintEvent*);private:Ui::TransferlistWidgetClass ui;// 小三角的方位Derection m_derect;// 小三角的偏移量int m_offset;// 小三角的宽度int m_triangleWidth;// 小三角高度int m_triangleHeight;};
主要代码:
//设定无边框 背景透明ui.setupUi(this);setWindowFlags(Qt::FramelessWindowHint);setAttribute(Qt::WA_TranslucentBackground);
// 绘制小三角void TransferlistWidget::paintEvent(QPaintEvent*){QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing, true);painter.setPen(Qt::NoPen);painter.setBrush(QColor(0, 0, 0, 38));QPainterPath drawPath;// 小三角区域;QPolygon trianglePolygon;QRect myRect(ui.widget->x(), ui.widget->y(), ui.widget->width(), ui.widget->height());// 设置小三的具体位置int tri_pos_x = 0, tri_pos_y = 0;switch (m_derect){case left:{// 小三上边点的位置tri_pos_x = myRect.x();tri_pos_y = myRect.y();trianglePolygon << QPoint(tri_pos_x, tri_pos_y);trianglePolygon << QPoint(tri_pos_x - m_triangleWidth, tri_pos_y + m_triangleHeight / 2);trianglePolygon << QPoint(tri_pos_x, tri_pos_y + m_triangleHeight);}break;default:break;}drawPath.addRoundedRect(myRect, BORDER_RADIUS, BORDER_RADIUS);drawPath.addPolygon(trianglePolygon);painter.drawPath(drawPath);}// 设定显示位置void TransferlistWidget::myMove(QPoint point){int top_left_x = point.x(), top_left_y = point.y();switch (m_derect) {case left:{//top_left_x = m_triangleWidth;top_left_y = point.y() - m_triangleHeight / 2;move(QPoint(top_left_x, top_left_y));}break;default:break;}}
4、显示和隐藏提示框
当鼠标放在按钮上时显示自定义气泡提示框,移开后提示框消失。
实现代码:
// 设置按钮提示窗口m_TransferlistDlg = new TransferlistWidget(this);m_TransferlistDlg->setDerection(TransferlistWidget::left);m_TransferlistDlg->setStartPos(20);m_TransferlistDlg->resize(400,300);m_TransferlistDlg->hide();//为QPushButton和QLabel安装事件过滤器ui.transferlistButton->installEventFilter(this);m_TransferlistDlg->installEventFilter(this);
// 重载虚函数virtual bool eventFilter(QObject* watched, QEvent* event);// 虚函数实现bool MyGlobalMap::eventFilter(QObject* watched, QEvent* event){if (ui.transferlistButton == watched || m_TransferlistDlg == watched){if (QEvent::Enter == event->type()) {//鼠标进入if (m_TransferlistDlg->isHidden()){m_TransferlistDlg->show();QPoint point = ui.transferlistButton->pos();m_TransferlistDlg->myMove(point);m_TransferlistDlg->raise();//显示最顶层return true;}}else if (QEvent::Leave == event->type()) {//鼠标离开if (!m_TransferlistDlg->isHidden()){//判断鼠标是否在控件上if (!ui.transferlistButton->geometry().contains(this->mapFromGlobal(QCursor::pos()))&& !m_TransferlistDlg->geometry().contains(this->mapFromGlobal(QCursor::pos()))){m_TransferlistDlg->hide();return true;}}}}return QWidget::eventFilter(watched, event);}
如果觉得《Qt实现侧边栏显示隐藏以及自定义提示框》对你有帮助,请点赞、收藏,并留下你的观点哦!