查看完整版本: [-- Qt编写超级多态按钮WKButton --]

QTCN开发网 -> Qt 作品展 -> Qt编写超级多态按钮WKButton [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

liudianwu 2018-03-16 14:00

Qt编写超级多态按钮WKButton

一个朋友需要定制一个按钮,部分需求如下:
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.可以显示图片,当显示图片时自动覆盖背景颜色和文字,但保留边框和圆角。
实现效果:
[attachment=18624]
集成在QUC自定义控件中
[attachment=19370]

[attachment=18622]
[attachment=18623]
核心代码:
  1. void WKButton::paintEvent(QPaintEvent *)
    {
        //绘制准备工作,启用反锯齿
        QPainter painter(this);
        painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

        //绘制背景
        drawBg(&painter);
        //绘制文字
        drawText(&painter);
    }

    void WKButton::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 WKButton::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();
    }



jimiy 2018-03-16 15:57
刘大神,能否发一份完整版给晚辈 lee132264@163.com 膜拜了

liuchangyin 2018-03-19 08:50
漂亮

哥依然潇洒 2018-03-27 08:41
原来paintevent还能这样用!厉害了!

sa12010055 2018-03-27 09:29
刘前辈,目前在学习Qt,看了您的文章受益很多。源码能发一份给我,供我参考学习一下,谢谢了~~

596042122@qq.com

向之想 2018-03-29 17:19
刘大神能否给再下发一份,学习下
daxiangs@126.com

autogyc 2018-03-31 08:21

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

kunge98321 2018-04-02 21:03
前辈,看了您的文章受益很多。源码能发一份给我,仅供参考,谢谢了。。。
183996768@qq.com

kong1990730 2018-04-08 18:15
大牛  发我一个   707469161@qq.com

liuchangyin 2018-04-09 10:03
漂亮

青春的年代 2018-04-10 13:59
谢谢分享我得学习

doublelight 2018-04-10 20:46
哭天抢地求楼主分享一个,304369331@qq.com

bxy21cn 2018-04-12 11:01
大神,也给来一份吧,bxy21cn@qq.com,谢谢!

luhanna1981 2018-04-13 09:07
大神,可不可以发一份参考一下m18854116610@163.com

飞舞的白雪 2018-04-26 22:08
大侠,能求一份源代码学习么?1737178399@qq.com

zhanglyl 2018-04-27 16:31
    

galaxy 2018-05-16 11:19
Qt和QWidget的绘图机制研究的很透了,可否分享QUC完整源码603842151@qq.com

cqu_keith 2018-06-01 21:31
跪求一份源码755170776@qq.com


查看完整版本: [-- Qt编写超级多态按钮WKButton --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled