Qt编写导航按钮
做各种各样的界面的时候,经常需要做一排按钮用于切换到对应界面,俗称导航按钮或者导航菜单,参照过各种各样的主界面导航布局,特意编写导航按钮自定义控件,结合各种情况,继承自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编写导航按钮的更多相关文章
- Qt编写的开源帖子集合(懒人专用)
回顾自己学习Qt以来九年了,在这九年多时间里面,从本论坛学习不到不少的东西,今天特意整了一下自己开源过的资源的帖子,整理一起方便大家直接跳转下载,不统计不知道,一统计吓一跳,不知不觉开源了这么多代码, ...
- Qt编写自定义控件11-设备防区按钮控件
前言 在很多项目应用中,需要根据数据动态生成对象显示在地图上,比如地图标注,同时还需要可拖动对象到指定位置显示,能有多种状态指示,安防领域一般用来表示防区或者设备,可以直接显示防区号,有多种状态颜色指 ...
- Qt编写自定义控件9-导航按钮控件
前言 导航按钮控件,主要用于各种漂亮精美的导航条,我们经常在web中看到导航条都非常精美,都是html+css+js实现的,还自带动画过度效果,Qt提供的qss其实也是无敌的,支持基本上所有的CSS2 ...
- Qt编写自定义控件8-动画按钮组控件
前言 动画按钮组控件可以用来当做各种漂亮的导航条用,既可以设置成顶部底部+左侧右侧,还自带精美的滑动效果,还可以设置悬停滑动等各种颜色,原创作者雨田哥(QQ:3246214072),驰骋Qt控件界多年 ...
- Qt编写自定义控件46-树状导航栏
一.前言 树状导航栏控件是所有控件中最牛逼最经典最厉害的一个,在很多购买者中,使用频率也是最高,因为该导航控件集合了非常多的展示效果,比如左侧图标+右侧箭头+元素前面的图标设置+各种颜色设置等,全部涵 ...
- Qt编写自定义控件42-开关按钮
一.前言 从2010年进入互联网+智能手机时代以来,各种各样的APP大行其道,手机上面的APP有很多流行的元素,开关按钮个人非常喜欢,手机QQ.360卫士.金山毒霸等,都有很多开关控制一些操作,在Qt ...
- Qt编写自定义控件38-高亮按钮
一.前言 高亮按钮控件,既可以作为类似于交通指示灯使用,也可以作为设备状态指示灯使用,控件内置多套颜色风格,还可以自己设置颜色风格,按钮可以增加文字显示,非常适合需要在状态设备上显示小量的文字展示,按 ...
- Qt编写自定义控件37-发光按钮(会呼吸的痛)
一.前言 这个控件是好早以前写的,已经授权过好几个人开源过此控件代码,比如红磨坊小胖,此控件并不是来源于真实需求,而仅仅是突发奇想,类似于星星的闪烁,越到边缘越来越淡,定时器动态改变边缘发光的亮度,产 ...
- Qt编写自定义控件30-颜色多态按钮
一.前言 这个控件一开始打算用样式表来实现,经过初步的探索,后面发现还是不够智能以及不能完全满足需求,比如要在此控件设置多个角标,这个用QSS就很难实现,后面才慢慢研究用QPainter来绘制,我记得 ...
随机推荐
- Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)
很多时候前端都需要调用后台服务实现交互功能,常见的数据交换格式多是JSON或XML,这里主要讲解Spring MVC为前端提供JSON格式的数据并实现与前台交互.RESTful则是一种软件架构风格.设 ...
- OpenCV 实现图片的水平投影与垂直投影,并进行行分割
对于印刷体图片来说,进行水平投影和垂直投影可以很快的进行分割,本文就在OpenCV中如何进行水平投影和垂直投影通过代码进行说明. 水平投影:二维图像在y轴上的投影 垂直投影:二维图像在x轴上的投影 由 ...
- web前端素材整理汇总
最近一直搞前端开发,整理下前端用的一些常用素材,分享给大家 框架类 Vue:https://cn.vuejs.org/ iview:https://www.iviewui.com/ 插件类 Jquer ...
- Effective Java 第三版——2. 当构造方法参数过多时使用builder模式
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- J2EE十三个规范小结
J2ee是我们步入java学习的一个開始.它将开启这趟奇幻之旅,Java是一种简单的,跨平台的,面向对象的,分布式的.解释的.健壮的安全的.结构的中立的,可移植的.性能非常优异的多线程的,动态的语言. ...
- Spark修炼之道(进阶篇)——Spark入门到精通:第九节 Spark SQL执行流程解析
1.总体执行流程 使用下列代码对SparkSQL流程进行分析.让大家明确LogicalPlan的几种状态,理解SparkSQL总体执行流程 // sc is an existing SparkCont ...
- Android Library projetcts cannot be exported.
记一次比較无语的犯错,前几天我在紧急打包一个apk的时候.遇到了这样一个异常:Android Library projetcts cannot be exported. 异常提示截图例如以下: wat ...
- scrapy里的selector,不能有正则提取
参考:http://blog.csdn.net/dawnranger/article/details/50037703 Selector 有一个 .re() 方法,用来通过正则表达式来提取数据. 不同 ...
- java 单例模式学习笔记
1.单例模式概述 单例模式就是确保类在内存中只有一个对象,该实例必须自动创建,并且对外提供. 2.优缺点 优点:在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模 ...
- NodeJs学习笔记(五)---单元测试补充
今天早上继续研究Mocha,忽然发现一个问题,我的大部分程序都是需要登录验证的,所以需要预先登录之后才能进行下一步测试,就开始在网上找答案,发现没有这种资料,很疑惑,最后发现其实是自己太笨了,因为这个 ...