• 9097阅读
  • 17回复

Qt编写超级多态按钮WKButton [复制链接]

上一主题 下一主题
离线liudianwu
 

图酷模式  只看楼主 倒序阅读 楼主  发表于: 2018-03-16
一个朋友需要定制一个按钮部分需求如下:
1.可以设置圆角(Radius)值。
2.可以设置边框的粗细(BorderSize)和颜色(BorderColor)
3.背景颜色有两种颜色RColor和PColor。
4.背景颜色显示模式有3种:
a)松开状态的颜色为RColor;按下状态的颜色为PColor。
b)松开状态的颜色为按键上半部分是RColor,按键下半部分为PColor;按下状态的颜色为按键上半部分是PColor,按键下半部分为RColor。
c)松开状态的颜色为RColor到PColor的渐变色;按下状态的颜色为按键上半部分是PColor到RColor的渐变色。
5.按键内部可以显示3行文字(Text[3]),并对每行文字设置字体、对齐、大小、颜色。
6.可以处理鼠标按下、松开、移动、拖拽的事件
7.可以显示图片,当显示图片时自动覆盖背景颜色和文字,但保留边框和圆角。
实现效果:

集成在QUC自定义控件中




核心代码:
  1. void WKButton::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. void WKButton::drawBg(QPainter *painter)
  12. {
  13.     painter->save();
  14.     //设置边框颜色及宽度
  15.     QPen pen;
  16.     pen.setColor(borderColor);
  17.     pen.setWidthF(borderWidth);
  18.     painter->setPen(pen);
  19.     //绘制区域要减去边框宽度
  20.     QRect rect;
  21.     rect.setX(borderWidth);
  22.     rect.setY(borderWidth);
  23.     rect.setWidth(width() - borderWidth * 2);
  24.     rect.setHeight(height() - borderWidth * 2);
  25.     //如果背景图片存在则显示背景图片,否则显示背景色
  26.     if (!bgImage.isNull()) {
  27.         //等比例缩放绘制
  28.         QPixmap img = bgImage.scaled(rect.width(), rect.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
  29.         painter->drawPixmap((this->rect().width() - img.width()) / 2, (this->rect().height() - img.height()) / 2, img);
  30.     } else {
  31.         if (colorMode == ColorMode_Normal) {
  32.             if (isPressed) {
  33.                 painter->setBrush(QBrush(pressedColor));
  34.             } else {
  35.                 painter->setBrush(QBrush(normalColor));
  36.             }
  37.         } else if (colorMode == ColorMode_Replace) {
  38.             QLinearGradient gradient(QPoint(0, 0), QPoint(0, height()));
  39.             if (isPressed) {
  40.                 gradient.setColorAt(0.0, pressedColor);
  41.                 gradient.setColorAt(0.49, pressedColor);
  42.                 gradient.setColorAt(0.50, normalColor);
  43.                 gradient.setColorAt(1.0, normalColor);
  44.             } else {
  45.                 gradient.setColorAt(0.0, normalColor);
  46.                 gradient.setColorAt(0.49, normalColor);
  47.                 gradient.setColorAt(0.50, pressedColor);
  48.                 gradient.setColorAt(1.0, pressedColor);
  49.             }
  50.             painter->setBrush(gradient);
  51.         } else if (colorMode == ColorMode_Shade) {
  52.             QLinearGradient gradient(QPoint(0, 0), QPoint(0, height()));
  53.             if (isPressed) {
  54.                 gradient.setColorAt(0.0, pressedColor);
  55.                 gradient.setColorAt(1.0, normalColor);
  56.             } else {
  57.                 gradient.setColorAt(0.0, normalColor);
  58.                 gradient.setColorAt(1.0, pressedColor);
  59.             }
  60.             painter->setBrush(gradient);
  61.         }
  62.         painter->drawRoundedRect(rect, borderRadius, borderRadius);
  63.     }
  64.     painter->restore();
  65. }
  66. void WKButton::drawText(QPainter *painter)
  67. {
  68.     if (!bgImage.isNull()) {
  69.         return;
  70.     }
  71.     painter->save();
  72.     //如果要显示角标,则重新计算显示文字的区域
  73.     if (showSuperText) {
  74.         int offset = 3;
  75.         QRect rect;
  76.         rect.setX(borderWidth * offset);
  77.         rect.setY(borderWidth);
  78.         rect.setWidth(width() - borderWidth * offset * 2);
  79.         rect.setHeight(height() - borderWidth * 2);
  80.         Qt::Alignment alignment = Qt::AlignCenter;
  81.         if (superTextAlign == TextAlign_Top_Left) {
  82.             alignment = Qt::AlignTop | Qt::AlignLeft;
  83.         } else if (superTextAlign == TextAlign_Top_Center) {
  84.             alignment = Qt::AlignTop | Qt::AlignHCenter;
  85.         } else if (superTextAlign == TextAlign_Top_Right) {
  86.             alignment = Qt::AlignTop | Qt::AlignRight;
  87.         } else if (superTextAlign == TextAlign_Center_Left) {
  88.             alignment = Qt::AlignLeft | Qt::AlignVCenter;
  89.         } else if (superTextAlign == TextAlign_Center_Center) {
  90.             alignment = Qt::AlignHCenter | Qt::AlignVCenter;
  91.         } else if (superTextAlign == TextAlign_Center_Right) {
  92.             alignment = Qt::AlignRight | Qt::AlignVCenter;
  93.         } else if (superTextAlign == TextAlign_Bottom_Left) {
  94.             alignment = Qt::AlignBottom | Qt::AlignLeft;
  95.         } else if (superTextAlign == TextAlign_Bottom_Center) {
  96.             alignment = Qt::AlignBottom | Qt::AlignHCenter;
  97.         } else if (superTextAlign == TextAlign_Bottom_Right) {
  98.             alignment = Qt::AlignBottom | Qt::AlignRight;
  99.         }
  100.         //绘制角标
  101.         painter->setPen(superTextColor);
  102.         painter->setFont(superTextFont);
  103.         painter->drawText(rect, alignment, superText);
  104.     }
  105.     int offset = 5;
  106.     QRect rect;
  107.     rect.setX(borderWidth * offset);
  108.     rect.setY(borderWidth);
  109.     rect.setWidth(width() - borderWidth * offset * 2);
  110.     rect.setHeight(height() - borderWidth * 2);
  111.     Qt::Alignment alignment = Qt::AlignCenter;
  112.     if (textAlign == TextAlign_Top_Left) {
  113.         alignment = Qt::AlignTop | Qt::AlignLeft;
  114.     } else if (textAlign == TextAlign_Top_Center) {
  115.         alignment = Qt::AlignTop | Qt::AlignHCenter;
  116.     } else if (textAlign == TextAlign_Top_Right) {
  117.         alignment = Qt::AlignTop | Qt::AlignRight;
  118.     } else if (textAlign == TextAlign_Center_Left) {
  119.         alignment = Qt::AlignLeft | Qt::AlignVCenter;
  120.     } else if (textAlign == TextAlign_Center_Center) {
  121.         alignment = Qt::AlignHCenter | Qt::AlignVCenter;
  122.     } else if (textAlign == TextAlign_Center_Right) {
  123.         alignment = Qt::AlignRight | Qt::AlignVCenter;
  124.     } else if (textAlign == TextAlign_Bottom_Left) {
  125.         alignment = Qt::AlignBottom | Qt::AlignLeft;
  126.     } else if (textAlign == TextAlign_Bottom_Center) {
  127.         alignment = Qt::AlignBottom | Qt::AlignHCenter;
  128.     } else if (textAlign == TextAlign_Bottom_Right) {
  129.         alignment = Qt::AlignBottom | Qt::AlignRight;
  130.     }
  131.     painter->setPen(textColor);
  132.     painter->setFont(textFont);
  133.     painter->drawText(rect, alignment, text);
  134.     painter->restore();
  135. }


4条评分好评度+1贡献值+1金钱+10威望+1
galaxy 好评度 +1 Qt和QWidget的绘图机制研究的很透了,可否分享QUC完整源码603842151@qq.com 2018-05-16
galaxy 贡献值 +1 Qt和QWidget的绘图机制研究的很透了,可否分享QUC完整源码603842151@qq.com 2018-05-16
galaxy 威望 +1 Qt和QWidget的绘图机制研究的很透了,可否分享QUC完整源码603842151@qq.com 2018-05-16
galaxy 金钱 +10 Qt和QWidget的绘图机制研究的很透了,可否分享QUC完整源码603842151@qq.com 2018-05-16
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线jimiy

只看该作者 1楼 发表于: 2018-03-16
刘大神,能否发一份完整版给晚辈 lee132264@163.com 膜拜了
离线liuchangyin

只看该作者 2楼 发表于: 2018-03-19
漂亮

只看该作者 3楼 发表于: 2018-03-27
原来paintevent还能这样用!厉害了!
离线sa12010055

只看该作者 4楼 发表于: 2018-03-27
刘前辈,目前在学习Qt,看了您的文章受益很多。源码能发一份给我,供我参考学习一下,谢谢了~~

596042122@qq.com
离线向之想

只看该作者 5楼 发表于: 2018-03-29
刘大神能否给再下发一份,学习下
daxiangs@126.com
离线autogyc

只看该作者 6楼 发表于: 2018-03-31

大神,能否发份代码学习下?
邮箱autogaoyicai@sohu.com
离线kunge98321

只看该作者 7楼 发表于: 2018-04-02
前辈,看了您的文章受益很多。源码能发一份给我,仅供参考,谢谢了。。。
183996768@qq.com
离线kong1990730

只看该作者 8楼 发表于: 2018-04-08
大牛  发我一个   707469161@qq.com
离线liuchangyin

只看该作者 9楼 发表于: 2018-04-09
漂亮

只看该作者 10楼 发表于: 2018-04-10
谢谢分享我得学习
离线doublelight

只看该作者 11楼 发表于: 2018-04-10
哭天抢地求楼主分享一个,304369331@qq.com
离线bxy21cn

只看该作者 12楼 发表于: 2018-04-12
大神,也给来一份吧,bxy21cn@qq.com,谢谢!
离线luhanna1981

只看该作者 13楼 发表于: 2018-04-13
大神,可不可以发一份参考一下m18854116610@163.com

只看该作者 14楼 发表于: 2018-04-26
大侠,能求一份源代码学习么?1737178399@qq.com
离线zhanglyl

只看该作者 15楼 发表于: 2018-04-27
    
离线galaxy

只看该作者 16楼 发表于: 2018-05-16
Qt和QWidget的绘图机制研究的很透了,可否分享QUC完整源码603842151@qq.com
离线cqu_keith

只看该作者 17楼 发表于: 2018-06-01
跪求一份源码755170776@qq.com
快速回复
限100 字节
 
上一个 下一个