做各种各样的界面的时候,经常需要做一排按钮用于切换到对应界面,俗称导航按钮或者导航菜单,参照过各种各样的主界面导航布局,特意编写导航按钮自定义控件,结合各种情况,继承自QPushButton。已集成在QUC自定义控件中。

/**
* 导航按钮控件 作者:feiyangqingyun(QQ:517216493) 2017-12-19
* 1:可设置文字的左侧+右侧+顶部+底部间隔
* 2:可设置文字对齐方式
* 3:可设置显示倒三角/倒三角边长/倒三角位置/倒三角颜色
* 4:可设置显示图标/图标间隔/图标尺寸/正常状态图标/悬停状态图标/选中状态图标
* 5:可设置显示边框线条/线条宽度/线条间隔/线条位置/线条颜色
* 6:可设置正常背景颜色/悬停背景颜色/选中背景颜色
* 7:可设置正常文字颜色/悬停文字颜色/选中文字颜色
* 8:可设置背景颜色为画刷颜色
*/

本人有代码洁癖症,写代码处处讲究对称完美。如下图所示。

void NavButton::paintEvent(QPaintEvent *)
{
    //绘制准备工作,启用反锯齿
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);     //绘制背景
    drawBg(&painter);
    //绘制文字
    drawText(&painter);
    //绘制图标
    drawIcon(&painter);
    //绘制边框线条
    drawLine(&painter);
    //绘制右侧倒三角
    drawTriangle(&painter);
} void NavButton::drawBg(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);     int width = this->width();
    int height = this->height();     QRect bgRect;
    if (linePosition == LinePosition_Left) {
        bgRect = QRect(lineSpace, 0, width - lineSpace, height);
    } else if (linePosition == LinePosition_Right) {
        bgRect = QRect(0, 0, width - lineSpace, height);
    } else if (linePosition == LinePosition_Top) {
        bgRect = QRect(0, lineSpace, width, height - lineSpace);
    } else if (linePosition == LinePosition_Bottom) {
        bgRect = QRect(0, 0, width, height - lineSpace);
    }     //如果画刷存在则取画刷
    QBrush bgBrush;
    if (isChecked()) {
        bgBrush = checkBgBrush;
    } else if (hover) {
        bgBrush = hoverBgBrush;
    } else {
        bgBrush = normalBgBrush;
    }     if (bgBrush != Qt::NoBrush) {
        painter->setBrush(bgBrush);
    } else {
        //根据当前状态选择对应颜色
        QColor bgColor;
        if (isChecked()) {
            bgColor = checkBgColor;
        } else if (hover) {
            bgColor = hoverBgColor;
        } else {
            bgColor = normalBgColor;
        }         painter->setBrush(bgColor);
    }     painter->drawRect(bgRect);     painter->restore();
} void NavButton::drawText(QPainter *painter)
{
    painter->save();
    painter->setBrush(Qt::NoBrush);     //根据当前状态选择对应颜色
    QColor textColor;
    if (isChecked()) {
        textColor = checkTextColor;
    } else if (hover) {
        textColor = hoverTextColor;
    } else {
        textColor = normalTextColor;
    }     QRect textRect = QRect(paddingLeft, paddingTop, width() - paddingLeft - paddingRight, height() - paddingTop - paddingBottom);
    painter->setPen(textColor);
    painter->drawText(textRect, textAlign | Qt::AlignVCenter, text());     painter->restore();
} void NavButton::drawIcon(QPainter *painter)
{
    if (!showIcon) {
        return;
    }     painter->save();     QPixmap pix;
    if (isChecked()) {
        pix = iconCheck;
    } else if (hover) {
        pix = iconHover;
    } else {
        pix = iconNormal;
    }     if (!pix.isNull()) {
        //等比例平滑缩放图标
        pix = pix.scaled(iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
        painter->drawPixmap(iconSpace, (height() - iconSize.height()) / 2, pix);
    }     painter->restore();
} void NavButton::drawLine(QPainter *painter)
{
    if (!showLine) {
        return;
    }     if (!isChecked()) {
        return;
    }     painter->save();     QPen pen;
    pen.setWidth(lineWidth);
    pen.setColor(lineColor);
    painter->setPen(pen);     //根据线条位置设置线条坐标
    QPoint pointStart, pointEnd;
    if (linePosition == LinePosition_Left) {
        pointStart = QPoint(0, 0);
        pointEnd = QPoint(0, height());
    } else if (linePosition == LinePosition_Right) {
        pointStart = QPoint(width(), 0);
        pointEnd = QPoint(width(), height());
    } else if (linePosition == LinePosition_Top) {
        pointStart = QPoint(0, 0);
        pointEnd = QPoint(width(), 0);
    } else if (linePosition == LinePosition_Bottom) {
        pointStart = QPoint(0, height());
        pointEnd = QPoint(width(), height());
    }     painter->drawLine(pointStart, pointEnd);     painter->restore();
} void NavButton::drawTriangle(QPainter *painter)
{
    if (!showTriangle) {
        return;
    }     //选中或者悬停显示
    if (!hover && !isChecked()) {
        return;
    }     painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(triangleColor);     //绘制在右侧中间,根据设定的倒三角的边长设定三个点位置
    int width = this->width();
    int height = this->height();
    int midWidth = width / 2;
    int midHeight = height / 2;     QPolygon pts;
    if (trianglePosition == TrianglePosition_Left) {
        pts.setPoints(3, triangleLen, midHeight, 0, midHeight - triangleLen, 0, midHeight + triangleLen);
    } else if (trianglePosition == TrianglePosition_Right) {
        pts.setPoints(3, width - triangleLen, midHeight, width, midHeight - triangleLen, width, midHeight + triangleLen);
    } else if (trianglePosition == TrianglePosition_Top) {
        pts.setPoints(3, midWidth, triangleLen, midWidth - triangleLen, 0, midWidth + triangleLen, 0);
    } else if (trianglePosition == TrianglePosition_Bottom) {
        pts.setPoints(3, midWidth, height - triangleLen, midWidth - triangleLen, height, midWidth + triangleLen, height);
    }     painter->drawPolygon(pts);     painter->restore();
}

  

Qt编写导航按钮的更多相关文章

  1. Qt编写的开源帖子集合(懒人专用)

    回顾自己学习Qt以来九年了,在这九年多时间里面,从本论坛学习不到不少的东西,今天特意整了一下自己开源过的资源的帖子,整理一起方便大家直接跳转下载,不统计不知道,一统计吓一跳,不知不觉开源了这么多代码, ...

  2. Qt编写自定义控件11-设备防区按钮控件

    前言 在很多项目应用中,需要根据数据动态生成对象显示在地图上,比如地图标注,同时还需要可拖动对象到指定位置显示,能有多种状态指示,安防领域一般用来表示防区或者设备,可以直接显示防区号,有多种状态颜色指 ...

  3. Qt编写自定义控件9-导航按钮控件

    前言 导航按钮控件,主要用于各种漂亮精美的导航条,我们经常在web中看到导航条都非常精美,都是html+css+js实现的,还自带动画过度效果,Qt提供的qss其实也是无敌的,支持基本上所有的CSS2 ...

  4. Qt编写自定义控件8-动画按钮组控件

    前言 动画按钮组控件可以用来当做各种漂亮的导航条用,既可以设置成顶部底部+左侧右侧,还自带精美的滑动效果,还可以设置悬停滑动等各种颜色,原创作者雨田哥(QQ:3246214072),驰骋Qt控件界多年 ...

  5. Qt编写自定义控件46-树状导航栏

    一.前言 树状导航栏控件是所有控件中最牛逼最经典最厉害的一个,在很多购买者中,使用频率也是最高,因为该导航控件集合了非常多的展示效果,比如左侧图标+右侧箭头+元素前面的图标设置+各种颜色设置等,全部涵 ...

  6. Qt编写自定义控件42-开关按钮

    一.前言 从2010年进入互联网+智能手机时代以来,各种各样的APP大行其道,手机上面的APP有很多流行的元素,开关按钮个人非常喜欢,手机QQ.360卫士.金山毒霸等,都有很多开关控制一些操作,在Qt ...

  7. Qt编写自定义控件38-高亮按钮

    一.前言 高亮按钮控件,既可以作为类似于交通指示灯使用,也可以作为设备状态指示灯使用,控件内置多套颜色风格,还可以自己设置颜色风格,按钮可以增加文字显示,非常适合需要在状态设备上显示小量的文字展示,按 ...

  8. Qt编写自定义控件37-发光按钮(会呼吸的痛)

    一.前言 这个控件是好早以前写的,已经授权过好几个人开源过此控件代码,比如红磨坊小胖,此控件并不是来源于真实需求,而仅仅是突发奇想,类似于星星的闪烁,越到边缘越来越淡,定时器动态改变边缘发光的亮度,产 ...

  9. Qt编写自定义控件30-颜色多态按钮

    一.前言 这个控件一开始打算用样式表来实现,经过初步的探索,后面发现还是不够智能以及不能完全满足需求,比如要在此控件设置多个角标,这个用QSS就很难实现,后面才慢慢研究用QPainter来绘制,我记得 ...

随机推荐

  1. 【ASP.NET Core】运行原理之启动WebHost

    ASP.NET Core运行原理之启动WebHost 本节将分析WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().Build ...

  2. java系列视频教程下载

    1.马士兵J2SE基础录屏视频 珍藏版 链接:https://pan.baidu.com/s/1eRMJqkq    密码:qa66 2.spring视频教程 链接:https://pan.baidu ...

  3. WPF自定义产品框架

    在讲解之前先看一下效果,有助于理解: 这是客户端的效果图.整个产品分为两部分:1.WPF开发的展示效果的客户端   2.WCF开发的提供数据服务接口的服务端   本章主要讲解一下实际中开发WPF开发客 ...

  4. HDU2159--二维费用背包,三重背包

    FATE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  5. CS:APP3e 深入理解计算机系统_3e CacheLab实验

    详细的题目要求和资源可以到 http://csapp.cs.cmu.edu/3e/labs.html 或者 http://www.cs.cmu.edu/~./213/schedule.html 获取. ...

  6. javascript设计模式——适配器模式

    前面的话 适配器模式的作用是解决两个软件实体间的接口不兼容的问题.使用适配器模式之后,原本由于接口不兼容而不能工作的两个软件实体可以一起工作.适配器的别名是包装器(wrapper),这是一个相对简单的 ...

  7. (三)—Linux文件传输与mysql数据库安装

    文件传输工具使用    为了速成,关于linux系统的学习都先放一放,用到哪个知识点就查哪个,这里想在linux下装一些服务练练手,最先想到的就是装个mysql数据库试试. 因为我用的是虚拟机下的li ...

  8. outb,inb等I/Oport操作函数

    功能: 如 i386 .在差别 I/O 空间和内存空间的进程的 I/O 空间写入数据. outb()   I/O 上写入 8 位数据 ( 1 字节 ). outw() I/O 上写入 16 位数据 ( ...

  9. 深入了解MyBatis返回值

    深入了解MyBatis返回值 想了解返回值,我们须要了解resultType,resultMap以及接口方法中定义的返回值. 我们先看resultType和resultMap resultType和r ...

  10. Docker for Windows 使用入门

    欢迎来到Docker for Windows! Docker是用于创建Docker应用程序的完整开发平台,Docker for Windows是在Windows系统上开始使用Docker的最佳方式. ...