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来绘制,我记得 ...
随机推荐
- 永中DCS文档转换服务其它产品对比
一.利用DCOM配置直接操作Office文件 作用:读取文件内容,导出Html文件 优势:免费 劣势:1.服务器上必须安装Office软件 2.配置麻烦,正如微软所说,读取Office不是这么干的. ...
- CCF-201604-1-折点计数
问题描述 试题编号: 201604-1 试题名称: 折点计数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定n个整数表示一个商店连续n天的销售量.如果某天之前销售量在增长 ...
- codeup模拟赛 进击的二叉查找数
问题 B: 进击的二叉查找树 时间限制: 1 Sec 内存限制: 64 MB 提交: 1017 解决: 379 提交状态 题目描述 给定1~N的两个排列,使用这两个排列分别构建两棵二叉查找树(也就是通 ...
- yii2数据条件查询-where专题
条件查询 $customers = Customer::find()->where($cond)->all(); $cond就是我们所谓的条件,条件的写法也根据查询数据的不同存在差异,那么 ...
- SQL面试题:有A B C三列,用SQL语句实现:当A列大于B列时选择A列否则选择B列
.请教一个面试中遇到的SQL语句的查询问题 表中有A B C三列,用SQL语句实现:当A列大于B列时选择A列否则选择B列,当B列大于C列时选择B列否则选择C列. ------------------- ...
- spring boot + mybatis + hikaricp + swagger2 + jasypt
好久没写博客了记录下写过的东西,别到时候又忘了 文章前提:前面开发项目的时候数据池一直用的阿里的druid,这个数据池吧也不能说它不好,为什么现在想改成hikaricp数据池呢,完全是实用项目需要.d ...
- flask_login 整合 pyjwt + json 简易flask框架
现在很多框架都实现前后端分离,主要为了适应以下几个目的: 1,前后端的分离,可以使前端开发和后端开发更加分工明确,而不是后端还需要在视图模板中加入很多{% XXXX %}标签 2,是为了适应跨域调用或 ...
- 虚拟DOM详解
虚拟DOM简介 Virtual Dom可以看做一棵模拟了DOM树的JavaScript对象树,其主要是通过vnode,实现一个无状态的组件,当组件状态发生更新时,然后触发Virtual Dom数据的变 ...
- vue 二进制文件的下载(解决乱码和解压报错)
问题描述:项目中使用的是vue框架进行开发,因为文件下载存在权限问题,所以并不能通过 a 链接的 href 属性直接赋值 URL进行下载, (如果你的文件没有下载权限,可以直接通过href属性赋值UR ...
- Android 夜间模式changeskin小结
@author vivian8725118 @CSDN http://blog.csdn.net/vivian8725118 @简书 http://www.jianshu.com/p/832e9776 ...