一、前言

这个控件一开始打算用样式表来实现,经过初步的探索,后面发现还是不够智能以及不能完全满足需求,比如要在此控件设置多个角标,这个用QSS就很难实现,后面才慢慢研究用QPainter来绘制,我记得当时接到这个定制控件任务的时候是2016年,那时候对QPainter的使用还不是很熟悉,也就是从此控件开始,逐步研究QPainter的绘制,把所有的内置函数都使用一遍,最终用的越来越熟悉,使得后来到了心中有坐标,万物皆painter的境界,可能就像武林中所说的打通了任督二脉吧。

本控件除了可以设置常规的圆角角度,边框宽度,边框颜色,正常颜色,按下颜色以外,还可以设置各个角标和正文文字内容/字体/对齐方式/颜色,同时还要提供三种颜色展示模式,松开按下两种颜色,按下松开颜色上下交替,按下松开颜色渐变交替。QLinearGradient是个好东西,各种颜色交替效果全靠它来实现。

二、实现的功能

* 1:可设置圆角角度,边框宽度

* 2:可设置角标和正文文字内容/字体/对齐方式/颜色

* 3:可设置边框颜色,正常颜色,按下颜色

* 4:可设置背景图片

* 5:可设置按钮颜色模式

三、效果图

四、核心代码

bool ColorButton::eventFilter(QObject *watched, QEvent *event){ if (!isEnabled()) { return QWidget::eventFilter(watched, event); } static QPoint lastPoint; if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *e = static_cast(event); if (this->rect().contains(e->pos()) && (e->button() == Qt::LeftButton)) { lastPoint = e->pos(); isPressed = true; update(); } } else if (event->type() == QEvent::MouseMove && isPressed && canMove) { QMouseEvent *e = static_cast(event); int dx = e->pos().x() - lastPoint.x(); int dy = e->pos().y() - lastPoint.y(); this->move(this->x() + dx, this->y() + dy); return true; } else if (event->type() == QEvent::MouseButtonRelease && isPressed) { isPressed = false; update(); } return QWidget::eventFilter(watched, event);}void ColorButton::paintEvent(QPaintEvent *){ //绘制准备工作,启用反锯齿 QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); //绘制背景 drawBg(&painter); //绘制文字 drawText(&painter);}void ColorButton::drawBg(QPainter *painter){ painter->save(); //设置边框颜色及宽度 QPen pen; pen.setColor(borderColor); pen.setWidthF(borderWidth); painter->setPen(pen); //绘制区域要减去边框宽度 QRect rect; rect.setX(borderWidth); rect.setY(borderWidth); rect.setWidth(width() - borderWidth * 2); rect.setHeight(height() - borderWidth * 2); //如果背景图片存在则显示背景图片,否则显示背景色 if (!bgImage.isNull()) { //等比例缩放绘制 QPixmap img = bgImage.scaled(rect.width(), rect.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); painter->drawPixmap((this->rect().width() - img.width()) / 2, (this->rect().height() - img.height()) / 2, img); } else { if (colorMode == ColorMode_Normal) { if (isPressed) { painter->setBrush(QBrush(pressedColor)); } else { painter->setBrush(QBrush(normalColor)); } } else if (colorMode == ColorMode_Replace) { QLinearGradient gradient(QPoint(0, 0), QPoint(0, height())); if (isPressed) { gradient.setColorAt(0.0, pressedColor); gradient.setColorAt(0.49, pressedColor); gradient.setColorAt(0.50, normalColor); gradient.setColorAt(1.0, normalColor); } else { gradient.setColorAt(0.0, normalColor); gradient.setColorAt(0.49, normalColor); gradient.setColorAt(0.50, pressedColor); gradient.setColorAt(1.0, pressedColor); } painter->setBrush(gradient); } else if (colorMode == ColorMode_Shade) { QLinearGradient gradient(QPoint(0, 0), QPoint(0, height())); if (isPressed) { gradient.setColorAt(0.0, pressedColor); gradient.setColorAt(1.0, normalColor); } else { gradient.setColorAt(0.0, normalColor); gradient.setColorAt(1.0, pressedColor); } painter->setBrush(gradient); } painter->drawRoundedRect(rect, borderRadius, borderRadius); } painter->restore();}void ColorButton::drawText(QPainter *painter){ if (!bgImage.isNull()) { return; } painter->save(); //如果要显示角标,则重新计算显示文字的区域 if (showSuperText) { int offset = 3; QRect rect; rect.setX(borderWidth * offset); rect.setY(borderWidth); rect.setWidth(width() - borderWidth * offset * 2); rect.setHeight(height() - borderWidth * 2); Qt::Alignment alignment = Qt::AlignCenter; if (superTextAlign == TextAlign_Top_Left) { alignment = Qt::AlignTop | Qt::AlignLeft; } else if (superTextAlign == TextAlign_Top_Center) { alignment = Qt::AlignTop | Qt::AlignHCenter; } else if (superTextAlign == TextAlign_Top_Right) { alignment = Qt::AlignTop | Qt::AlignRight; } else if (superTextAlign == TextAlign_Center_Left) { alignment = Qt::AlignLeft | Qt::AlignVCenter; } else if (superTextAlign == TextAlign_Center_Center) { alignment = Qt::AlignHCenter | Qt::AlignVCenter; } else if (superTextAlign == TextAlign_Center_Right) { alignment = Qt::AlignRight | Qt::AlignVCenter; } else if (superTextAlign == TextAlign_Bottom_Left) { alignment = Qt::AlignBottom | Qt::AlignLeft; } else if (superTextAlign == TextAlign_Bottom_Center) { alignment = Qt::AlignBottom | Qt::AlignHCenter; } else if (superTextAlign == TextAlign_Bottom_Right) { alignment = Qt::AlignBottom | Qt::AlignRight; } //绘制角标 painter->setPen(superTextColor); painter->setFont(superTextFont); painter->drawText(rect, alignment, superText); } int offset = 5; QRect rect; rect.setX(borderWidth * offset); rect.setY(borderWidth); rect.setWidth(width() - borderWidth * offset * 2); rect.setHeight(height() - borderWidth * 2); Qt::Alignment alignment = Qt::AlignCenter; if (textAlign == TextAlign_Top_Left) { alignment = Qt::AlignTop | Qt::AlignLeft; } else if (textAlign == TextAlign_Top_Center) { alignment = Qt::AlignTop | Qt::AlignHCenter; } else if (textAlign == TextAlign_Top_Right) { alignment = Qt::AlignTop | Qt::AlignRight; } else if (textAlign == TextAlign_Center_Left) { alignment = Qt::AlignLeft | Qt::AlignVCenter; } else if (textAlign == TextAlign_Center_Center) { alignment = Qt::AlignHCenter | Qt::AlignVCenter; } else if (textAlign == TextAlign_Center_Right) { alignment = Qt::AlignRight | Qt::AlignVCenter; } else if (textAlign == TextAlign_Bottom_Left) { alignment = Qt::AlignBottom | Qt::AlignLeft; } else if (textAlign == TextAlign_Bottom_Center) { alignment = Qt::AlignBottom | Qt::AlignHCenter; } else if (textAlign == TextAlign_Bottom_Right) { alignment = Qt::AlignBottom | Qt::AlignRight; } painter->setPen(textColor); painter->setFont(textFont); painter->drawText(rect, alignment, text); painter->restore();}

六、控件介绍

1. 超过149个精美控件,涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,flatui、高亮按钮、滑动选择器、农历等。远超qwt集成的控件数量。

2. 每个类都可以独立成一个单独的控件,零耦合,每个控件一个头文件和一个实现文件,不依赖其他文件,方便单个控件以源码形式集成到项目中,较少代码量。qwt的控件类环环相扣,高度耦合,想要使用其中一个控件,必须包含所有的代码。

3. 全部纯Qt编写,QWidget+QPainter绘制,支持Qt4.6到Qt5.12的任何Qt版本,支持mingw、msvc、gcc等编译器,支持任意操作系统比如windows+linux+mac+嵌入式linux等,不乱码,可直接集成到Qt Creator中,和自带的控件一样使用,大部分效果只要设置几个属性即可,极为方便。

4. 每个控件都有一个对应的单独的包含该控件源码的DEMO,方便参考使用。同时还提供一个所有控件使用的集成的DEMO。

5. 每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。

6. 每个控件默认配色和demo对应的配色都非常精美。

7. 超过130个可见控件,6个不可见控件。

8. 部分控件提供多种样式风格选择,多种指示器样式选择。

9. 所有控件自适应窗体拉伸变化。

10. 集成自定义控件属性设计器,支持拖曳设计,所见即所得,支持导入导出xml格式。

11. 自带activex控件demo,所有控件可以直接运行在ie浏览器中。

12. 集成fontawesome图形字体+阿里巴巴iconfont收藏的几百个图形字体,享受图形字体带来的乐趣。

13. 所有控件最后生成一个dll动态库文件,可以直接集成到qtcreator中拖曳设计使用。

14. 目前已经有qml版本,后期会考虑出pyqt版本,如果用户需求量很大的话。

qt creator 设置按键颜色_Qt编写自定义控件30-颜色多态按钮相关推荐

  1. qt qss设置字体大小_Qt编写自定义控件55-手机通讯录

    一.前言 前面几篇文章中的控件基本上难度系数接近0,甚至有凑控件数量的嫌疑,这次必须来一个强悍的控件,本控件难度系数在所有控件中排前五,代码量也不少,头文件都550行,实现文件1600行,为什么这么多 ...

  2. qt qss设置字体大小_Qt编写自定义控件70-扁平化flatui

    一.前言 对于现在做前端开发人员来说,FlatUI肯定不陌生,最近几年扁平化的设计越来越流行,大概由于现在PC端和移动端的设备的分辨率越来越高,扁平化反而看起来更让人愉悦,而通过渐变色产生的质感色彩反 ...

  3. 在qt实现手机通讯录系统_Qt编写自定义控件55-手机通讯录

    一.前言 前面几篇文章中的控件基本上难度系数接近0,甚至有凑控件数量的嫌疑,这次必须来一个强悍的控件,本控件难度系数在所有控件中排前五,代码量也不少,头文件都550行,实现文件1600行,为什么这么多 ...

  4. datetimepicker控件怎么改变hover颜色_Qt编写自定义控件9-导航按钮控件

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

  5. Qt Creator设置Conan

    Qt Creator设置Conan 设置Conan 设置Conan Conan是一个C / C ++程序包管理器,可加快将C或C ++库集成到您自己的项目中的速度.它在所有受支持的开发平台上都可用. ...

  6. Qt Creator设置Meson

    Qt Creator设置Meson 设置Meson 添加Meson工具 编辑meson版本说明 代码完成和外部库 当前meson支持限制 设置Meson Meson是一个使用Ninja作为主要后端的开 ...

  7. Qt Creator设置Nimble

    Qt Creator设置Nimble 设置Nimble 搭建开发环境 创建灵活的应用程序 设置Nimble Nimble是Nim编程语言的程序包管理器.它与Nim一起提供,并使用Nim编译器生成Win ...

  8. Qt Creator设置一个Autotools项目

    Qt Creator设置一个Autotools项目 设置一个Autotools项目 设置一个Autotools项目 AutotoolsProjectManager是用于自动工具支持的插件.默认情况下它 ...

  9. Qt Creator设置Qbs

    Qt Creator设置Qbs 设置Qbs 构建Qbs 指定Qbs设置 设置Qbs 要使用Qbs构建项目,必须为该项目创建.qbs文件.您可以使用Qt Creator创建使用Qbs构建的C或C ++项 ...

最新文章

  1. qchart画完以后删除_Unity2019基础教程:TileMap搭建像素画场景关卡
  2. 口碑扑街光环不在,2018将是苹果手机最难熬的年头!
  3. Promise读取多个文件
  4. 取本地数据_深入理解Kafka服务端之Follower副本如何同步Leader副本的数据
  5. GraphQL 到底有什么魔力?
  6. Python 第三方库之 docxtpl (处理word文档)
  7. php开发中常用函数总结,PHP开发中常用函数总结
  8. sql语法、特殊符号及正则表达式的使用
  9. ubuntu16.04 jdk安装及环境配置
  10. 论文阅读笔记(五)——FD-MOBILENET
  11. 杀毒软件可能令企业用户陷入更大危机
  12. 海康人脸库上传人脸图片和人员扩展信息踩坑记
  13. 推荐PDG阅读器UnicornViewer
  14. 走进波分 -- 16.Optix OSN9800产品介绍
  15. 火狐浏览器不支持html5,解决火狐浏览器扩展版本不兼容问题
  16. 定企业生死的中台,到底长啥样?
  17. 关于TC Games针对没有耳机接口的Type-C用户玩手游如何传音和语音
  18. 脑肿瘤的影像组学:图像评估、定量特征描述和机器学习方法
  19. 人工智能AI实训平台
  20. SQL语句中EXISTS的使用详解及示例

热门文章

  1. SEO优化:WordPress发布文章主动推送到百度,加快收录保护原创
  2. Apache AB 性能测试
  3. Python 中非常狗的一个坑(在 `a={1:2},`后面多了一个逗号,自动被判为 tuple 类型了)
  4. SQL Server对Xml字段的操作
  5. 《强化学习》中的第15章:神经科学
  6. 数字后端基本概念介绍<site>
  7. android支付宝开放平台开发,支付宝开放平台支付更新升级全解析
  8. java可以实现agv调度吗_AGV路线优化及实时调度
  9. corosync配置与详解
  10. SQL基础--gt; 约束(CONSTRAINT)