做各种各样的界面的时候,经常需要做一排按钮用于切换到对应界面,俗称导航按钮或者导航菜单,参照过各种各样的主界面导航布局,特意编写导航按钮自定义控件,结合各种情况,继承自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. C# 中枚举的一点研究(跳过一些net坑的研究而已)

    之前一直使用Enum.Parse()将字符串转为枚举,没有深究,后面发现一个问题后对下面的Enum有了一个初步研究(.net 4.0).看下面代码. (留意,枚举类型是值类型,其值不能为Null,所以 ...

  2. 整合SSH时,遇到了org.springframework.beans.factory.BeanCreationException错误

    严重: StandardWrapper.Throwableorg.springframework.beans.factory.BeanCreationException: Error creating ...

  3. 大数加法之C语言函数法(只有正数版)

         由于某些原因,我于今天2017-4-19将我的博文搬到博客园了,以后我就在这里扎根了.         之前想过在博客写文章方便日后复习,但一直未能实现,所以,现在这篇是我个人人生中第一篇博 ...

  4. 逐步搭建Lamp环境之Linux的运行模式

    首先先来看几个概念,分别是:单用户.单任务.多用户.多任务 单用户: 是指操作系统一般只能由一个人同时进行登录 单任务: 是指操作系统只能同时处理一个任务 多用户: 是指操作系统可以允许由多个用户同时 ...

  5. 使用js做创建图片及删除图片 若有什么不对或不完整的地方,请大家提出来,谢谢

    首先我们要在<body>中创建一个按钮<button>来用作点击创建图片,在<button>中写一个点击事件(随便命名), 在创建一个<div>存放图片 ...

  6. Unity 5--全局光照技术

    本文整理自Unity全球官方网站,原文:UNITY 5 - LIGHTING AND RENDERING 简介全局光照,简称GI,是一个用来模拟光的互动和反弹等复杂行为的算法,要精确的仿真全局光照非常 ...

  7. 局域网使用的IP地址范围

    局域网可用的IP地址范围为: A类地址:10.0.0.0 - 10.255.255.255  B类地址:172.16.0.0 - 172.31.255.255 C类地址:192.168.0.0 -19 ...

  8. hdu 5225 Tom and permutation(回溯)

    题目链接:hdu 5225 Tom and permutation #include <cstdio> #include <cstring> #include <algo ...

  9. vue的组件和生命周期

    Vue里组件的通信 通信:传参.控制.数据共享(A操控B做一个事件) 模式:父子组件间.非父子组件 父组件可以将一条数据传递给子组件,这条数据可以是动态的,父组件的数据更改的时候,子组件接收的也会变化 ...

  10. C#开发微信门户及应用(48) - 在微信框架中整合CacheManager 缓存框架

    在我们的很多框架或者项目应用中,缓存在一定程度上可以提高程序的响应速度,以及减轻服务器的承载压力,因此在一些地方我们都考虑引入缓存模块,这篇随笔介绍使用开源缓存框架CacheManager来实现数据的 ...