• 46955阅读
  • 243回复

Qt编写导航按钮 [复制链接]

上一主题 下一主题
离线liudianwu
 

图酷模式  只看楼主 倒序阅读 楼主  发表于: 2017-12-24
做各种各样的界面的时候,经常需要做一排按钮用于切换到对应界面,俗称导航按钮或者导航菜单,参照过各种各样的主界面导航布局,特意编写导航按钮自定义控件,结合各种情况,继承自QPushButton。已集成在QUC自定义控件中。
作品已在另外一篇帖子开源,请见http://www.qtcn.org/bbs/read-htm-tid-66098.html
  1. /**
  2. * 导航按钮控件 作者:feiyangqingyun(QQ:517216493) 2017-12-19
  3. * 1:可设置文字的左侧+右侧+顶部+底部间隔
  4. * 2:可设置文字对齐方式
  5. * 3:可设置显示倒三角/倒三角边长/倒三角位置/倒三角颜色
  6. * 4:可设置显示图标/图标间隔/图标尺寸/正常状态图标/悬停状态图标/选中状态图标
  7. * 5:可设置显示边框线条/线条宽度/线条间隔/线条位置/线条颜色
  8. * 6:可设置正常背景颜色/悬停背景颜色/选中背景颜色
  9. * 7:可设置正常文字颜色/悬停文字颜色/选中文字颜色
  10. * 8:可设置背景颜色为画刷颜色
  11. */






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


主要代码:
  1. void NavButton::paintEvent(QPaintEvent *)
  2. {
  3.     //绘制准备工作,启用反锯齿
  4.     QPainter painter(this);
  5.     painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
  6.     //绘制背景
  7.     drawBg(&painter);
  8.     //绘制文字
  9.     drawText(&painter);
  10.     //绘制图标
  11.     drawIcon(&painter);
  12.     //绘制边框线条
  13.     drawLine(&painter);
  14.     //绘制右侧倒三角
  15.     drawTriangle(&painter);
  16. }
  17. void NavButton::drawBg(QPainter *painter)
  18. {
  19.     painter->save();
  20.     painter->setPen(Qt::NoPen);
  21.     int width = this->width();
  22.     int height = this->height();
  23.     QRect bgRect;
  24.     if (linePosition == LinePosition_Left) {
  25.         bgRect = QRect(lineSpace, 0, width - lineSpace, height);
  26.     } else if (linePosition == LinePosition_Right) {
  27.         bgRect = QRect(0, 0, width - lineSpace, height);
  28.     } else if (linePosition == LinePosition_Top) {
  29.         bgRect = QRect(0, lineSpace, width, height - lineSpace);
  30.     } else if (linePosition == LinePosition_Bottom) {
  31.         bgRect = QRect(0, 0, width, height - lineSpace);
  32.     }
  33.     //如果画刷存在则取画刷
  34.     QBrush bgBrush;
  35.     if (isChecked()) {
  36.         bgBrush = checkBgBrush;
  37.     } else if (hover) {
  38.         bgBrush = hoverBgBrush;
  39.     } else {
  40.         bgBrush = normalBgBrush;
  41.     }
  42.     if (bgBrush != Qt::NoBrush) {
  43.         painter->setBrush(bgBrush);
  44.     } else {
  45.         //根据当前状态选择对应颜色
  46.         QColor bgColor;
  47.         if (isChecked()) {
  48.             bgColor = checkBgColor;
  49.         } else if (hover) {
  50.             bgColor = hoverBgColor;
  51.         } else {
  52.             bgColor = normalBgColor;
  53.         }
  54.         painter->setBrush(bgColor);
  55.     }
  56.     painter->drawRect(bgRect);
  57.     painter->restore();
  58. }
  59. void NavButton::drawText(QPainter *painter)
  60. {
  61.     painter->save();
  62.     painter->setBrush(Qt::NoBrush);
  63.     //根据当前状态选择对应颜色
  64.     QColor textColor;
  65.     if (isChecked()) {
  66.         textColor = checkTextColor;
  67.     } else if (hover) {
  68.         textColor = hoverTextColor;
  69.     } else {
  70.         textColor = normalTextColor;
  71.     }
  72.     QRect textRect = QRect(paddingLeft, paddingTop, width() - paddingLeft - paddingRight, height() - paddingTop - paddingBottom);
  73.     painter->setPen(textColor);
  74.     painter->drawText(textRect, textAlign | Qt::AlignVCenter, text());
  75.     painter->restore();
  76. }
  77. void NavButton::drawIcon(QPainter *painter)
  78. {
  79.     if (!showIcon) {
  80.         return;
  81.     }
  82.     painter->save();
  83.     QPixmap pix;
  84.     if (isChecked()) {
  85.         pix = iconCheck;
  86.     } else if (hover) {
  87.         pix = iconHover;
  88.     } else {
  89.         pix = iconNormal;
  90.     }
  91.     if (!pix.isNull()) {
  92.         //等比例平滑缩放图标
  93.         pix = pix.scaled(iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
  94.         painter->drawPixmap(iconSpace, (height() - iconSize.height()) / 2, pix);
  95.     }
  96.     painter->restore();
  97. }
  98. void NavButton::drawLine(QPainter *painter)
  99. {
  100.     if (!showLine) {
  101.         return;
  102.     }
  103.     if (!isChecked()) {
  104.         return;
  105.     }
  106.     painter->save();
  107.     QPen pen;
  108.     pen.setWidth(lineWidth);
  109.     pen.setColor(lineColor);
  110.     painter->setPen(pen);
  111.     //根据线条位置设置线条坐标
  112.     QPoint pointStart, pointEnd;
  113.     if (linePosition == LinePosition_Left) {
  114.         pointStart = QPoint(0, 0);
  115.         pointEnd = QPoint(0, height());
  116.     } else if (linePosition == LinePosition_Right) {
  117.         pointStart = QPoint(width(), 0);
  118.         pointEnd = QPoint(width(), height());
  119.     } else if (linePosition == LinePosition_Top) {
  120.         pointStart = QPoint(0, 0);
  121.         pointEnd = QPoint(width(), 0);
  122.     } else if (linePosition == LinePosition_Bottom) {
  123.         pointStart = QPoint(0, height());
  124.         pointEnd = QPoint(width(), height());
  125.     }
  126.     painter->drawLine(pointStart, pointEnd);
  127.     painter->restore();
  128. }
  129. void NavButton::drawTriangle(QPainter *painter)
  130. {
  131.     if (!showTriangle) {
  132.         return;
  133.     }
  134.     //选中或者悬停显示
  135.     if (!hover && !isChecked()) {
  136.         return;
  137.     }
  138.     painter->save();
  139.     painter->setPen(Qt::NoPen);
  140.     painter->setBrush(triangleColor);
  141.     //绘制在右侧中间,根据设定的倒三角的边长设定三个点位置
  142.     int width = this->width();
  143.     int height = this->height();
  144.     int midWidth = width / 2;
  145.     int midHeight = height / 2;
  146.     QPolygon pts;
  147.     if (trianglePosition == TrianglePosition_Left) {
  148.         pts.setPoints(3, triangleLen, midHeight, 0, midHeight - triangleLen, 0, midHeight + triangleLen);
  149.     } else if (trianglePosition == TrianglePosition_Right) {
  150.         pts.setPoints(3, width - triangleLen, midHeight, width, midHeight - triangleLen, width, midHeight + triangleLen);
  151.     } else if (trianglePosition == TrianglePosition_Top) {
  152.         pts.setPoints(3, midWidth, triangleLen, midWidth - triangleLen, 0, midWidth + triangleLen, 0);
  153.     } else if (trianglePosition == TrianglePosition_Bottom) {
  154.         pts.setPoints(3, midWidth, height - triangleLen, midWidth - triangleLen, height, midWidth + triangleLen, height);
  155.     }
  156.     painter->drawPolygon(pts);
  157.     painter->restore();
  158. }



184条评分好评度+49贡献值+39金钱+265威望+38
nexito 好评度 +1 - 2020-12-25
nexito 贡献值 +1 - 2020-12-25
nexito 威望 +1 - 2020-12-25
nexito 金钱 +10 - 2020-12-25
jiangzx 金钱 +1 - 2020-12-25
18367160642 好评度 +1 优秀文章,支持!n神马都是浮云 2019-03-07
18367160642 贡献值 +1 优秀文章,支持!n神马都是浮云 2019-03-07
18367160642 威望 +1 优秀文章,支持!n神马都是浮云 2019-03-07
18367160642 金钱 +3 优秀文章,支持!n神马都是浮云 2019-03-07
unitcode 金钱 +1 优秀文章,支持!n神马都是浮云 2018-11-22
123456...19下一页
到第
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线微笑内敛

只看该作者 1楼 发表于: 2017-12-24
    
离线liuchangyin

只看该作者 2楼 发表于: 2017-12-25
离线liuchangyin

只看该作者 3楼 发表于: 2017-12-25
漂亮的界面
离线一只小鱼

只看该作者 4楼 发表于: 2017-12-25
  
离线liudianwu

只看该作者 5楼 发表于: 2017-12-25
回 一只小鱼 的帖子
一只小鱼:[表情]  [表情]  (2017-12-25 09:19) 

好评者留下邮箱,发本控件完整demo源码。
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线fariel

只看该作者 6楼 发表于: 2017-12-25
   大师越来越给力
离线vitty1984

只看该作者 7楼 发表于: 2017-12-25
vitty2005@163.com,好东西啊
离线huige3528

只看该作者 8楼 发表于: 2017-12-25
刘大神依旧很威武,来份代码瞧瞧   193323681@qq.com
离线vitty1984

只看该作者 9楼 发表于: 2017-12-25
好东西,vitty2005@163.com
离线wvjy001

只看该作者 10楼 发表于: 2017-12-25
离线zoemolly

只看该作者 11楼 发表于: 2017-12-25
多年QT老菜鸟前来学习 solmars@126.com
离线uu1000

只看该作者 12楼 发表于: 2017-12-25
,厉害,看看代码 uuvv1000@sohu.com
离线llwj0303

只看该作者 13楼 发表于: 2017-12-25
专注C++,专注Qt
离线街舞show

只看该作者 14楼 发表于: 2017-12-25
又是一波好控件啊。990882252@qq.com

只看该作者 15楼 发表于: 2017-12-25
刘大师出品,必属精品。547650721@qq.com。谢谢了。
离线hlr159hlr

只看该作者 16楼 发表于: 2017-12-26
刘大师出品,一直在学习。192842854@qq.com。谢谢了。
离线一只小鱼

只看该作者 17楼 发表于: 2017-12-26
感谢了 929077213@qq.com
离线liudianwu

只看该作者 18楼 发表于: 2017-12-26
vitty2005@163.com
193323681@qq.com
solmars@126.com
uuvv1000@sohu.com
479379320@qq.com
990882252@qq.com
547650721@qq.com
192842854@qq.com
929077213@qq.com
已发以上邮箱,还望记得给帖子评分!举手之劳!谢谢!
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线good_123

只看该作者 19楼 发表于: 2017-12-26
界面不错,3238363825@qq.com
离线renconan

只看该作者 20楼 发表于: 2017-12-26
大师出品,必属精品.谢谢大师819237590@qq.com
离线xdh873939316

只看该作者 21楼 发表于: 2017-12-26
感谢刘大师分享,,给5星好评。568470911@qq.com  刘大师出品,必属精品。。
离线rohgeo

只看该作者 22楼 发表于: 2017-12-27
刘老师出品,必属精品,5星好评。redgex@163.com
离线gonxa

只看该作者 23楼 发表于: 2017-12-27
精品必须支持!gonxa@163.com
离线lipanlin

只看该作者 24楼 发表于: 2017-12-27
精品!!!!!  lipanlin@126.com。谢谢了。
离线wyy626562203

只看该作者 25楼 发表于: 2017-12-28
感谢大神 1368299513@qq.com
离线thematic971

只看该作者 26楼 发表于: 2017-12-28
支持精品好帖 跟您学了不少知识 83945185@qq.com

只看该作者 27楼 发表于: 2017-12-28
支持刘大师,很喜欢刘大师作品的风格
369495512@qq.com
离线zqxwce007

只看该作者 28楼 发表于: 2017-12-29
优秀文章,支持!n神马都是浮云 zqxwce111@163.com
离线zengqingguo

只看该作者 29楼 发表于: 2017-12-29
大师出品,必属精品.谢谢大师 155226440@qq.com
离线liudianwu

只看该作者 30楼 发表于: 2017-12-29
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线fariel

只看该作者 31楼 发表于: 2017-12-29
前面忘了添加邮箱了,补个邮箱
fariel@126.com
离线lzh280

只看该作者 32楼 发表于: 2017-12-29
优秀文章,支持!n神马都是浮云 。邮箱:247095354@qq.com
离线morg

只看该作者 33楼 发表于: 2017-12-29
不错,谢谢   hz.qqmz@qq.com
离线qiji_2015

只看该作者 34楼 发表于: 2017-12-29
刘大师威武!受教了!shiyuluo2010@126.com
离线crazy

只看该作者 35楼 发表于: 2017-12-30
我顶
C/C++/Qt爱好者
邮箱: kevinlq0912@163.com
公众号: devstone
博客:http://kevinlq.com/
离线yyan_wwei8

只看该作者 36楼 发表于: 2017-12-30
离线chenjinb2008

只看该作者 37楼 发表于: 2017-12-31
支持刘大师,很喜欢刘大师作品。
chenjinb2008@163.com
离线yzq189424658

只看该作者 38楼 发表于: 2018-01-01
感谢分享, 向前辈学习.  yzq189424658@163.com 恳请发一份demo,感谢ing.
爱上学习,最我最大的进步。
离线zhucc3

只看该作者 39楼 发表于: 2018-01-01
感谢分享,向你学习,zhucc3@126.com,谢谢!
快速回复
限100 字节
 
上一个 下一个