随笔:Qt变色图像三态按钮

该文章介绍了一个基于Qt的自定义控件,该控件继承于QWidget,能显示图片并根据图片透明度设置前景色和背景色,支持边框设置及保持进入状态颜色的功能。它是一个三态按钮,鼠标操作时会改变颜色状态,并发出sn_clicked信号。
摘要由CSDN通过智能技术生成
//!
//! 随笔:Qt变色图像三态按钮
//!
//! == 控件简介 ==
//! 本次提供继承QWidget的按钮控件,提供显示图片功能,
//!     可根据图片透明度设置前景色和后景色,可添加边框和设置保持进入状态颜色,
//!     提供sn_clicked信号(鼠标抬起时发出)
//! == 控件简介 ==
//!
//! 结束语:
//!     文章后提供qbutt_col.h和qbutt_col.cpp文件
//!
#include "../qbutt_col.h"
#include "widget.h"
#include <iostream>
#include <QApplication>

using namespace std;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    qbutt_col bu1(&w);
    bu1.set_pic("/home/red/open/github/qt_hur/pic/m_one/m_2.png");
    bu1.set_col_foreground({0x808080,0x101010,0xff0000});  //前景色
    bu1.set_col_background({0xffaa44,0xff0000,0xffff00});  //背景色
    bu1.set_frame(true,QPen(QColor(0x010000),6));          //设置边框(宽度设置偶数可居中)
    bu1.show();

    w.connect(&bu1,&qbutt_col::sn_clicked,&w,[](){
        cout<<"sn_clicked"<<endl;
    });

    qbutt_col bu2(&w);
    bu2.move(bu1.width()+10,0);
    bu2.set_pic("/home/red/open/github/qt_hur/pic/m_one/m_2.png",100,200);
    bu2.set_col_foreground({0x808080,0x101010,0xff0000});  //前景色
    bu2.set_col_background({0xffaa44,0xff0000,0xffff00});  //背景色
    bu2.set_frame(true,QPen(QColor(0x010000),6));          //设置边框(宽度设置偶数可居中)
    bu2.set_keep_col(true); //保持进入颜色
    bu2.show();

    w.connect(&bu2,&qbutt_col::sn_clicked,&w,[](){
        cout<<"sn_clicked"<<endl;
    });

    return a.exec();
}
//!
//! qbutt_col.h
//!
#ifndef QBUTT_COL_H
#define QBUTT_COL_H

#include <QWidget>
#include <QPainter>
#include <QWidget>
#include <QMouseEvent>

//!
//! 功能:图片变色三态按钮
//! 用法:传入一张PNG图片(推荐黑白图片),传入三态RGB颜色,触发三态时根据RGB颜色改变图片颜色
//! 原理:保留PNG图片每个点位的颜色信息和透明度,如果点为不透明,根据三态RGB颜色改变点为颜色
//! 注意:前景指有颜色的像素点,背景指透明的像素点
//!
class qbutt_col : public QWidget
{
    Q_OBJECT
public:
    struct status
    {
        QColor normal;
        QColor enter;
        QColor press;
    };

public:
    explicit qbutt_col(QWidget *parent = nullptr);
    bool set_pic(QString pic,int w = 0,int h = 0);  //设置图片
    void set_col_foreground(status col);            //设置前景变化颜色
    void set_col_background(status col);            //设置背景变化颜色
    void set_keep_col(bool keep);                   //保持进入状态颜色
    void set_frame(bool frame,QPen pen);            //保持进入状态颜色 (QPen-width双倍数值可居中)

signals:
    emit void sn_clicked();

protected:
    //绘图事件
    void paintEvent(QPaintEvent *event) override;

    //触发事件
    void enterEvent(QEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void leaveEvent(QEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;

    //改变像素点颜色
    void ch_col_point(QColor col_fore,QColor col_back);

private:
    bool _keep_col = false;     //保存进入颜色
    bool _load_pic = false;     //加载图片
    bool _paint_frame = false;  //边框
    bool _paint_fore = false;   //前景
    bool _paint_back = false;   //背景
    status _fore;       //前景
    status _back;       //背景
    QPen _pen_frame;    //边框颜色
    QPixmap _pix;       //显示图片
    QVector<QVector<int>> _vec_alpha;   //记录像素点透明度
};

#endif // QBUTT_COL_H
//!
//! qbutt_col.cpp
//!
#include "qbutt_col.h"

qbutt_col::qbutt_col(QWidget *parent) : QWidget(parent)
{

}

bool qbutt_col::set_pic(QString pic,int w,int h)
{
    _load_pic = _pix.load(pic);
    if(_load_pic)
    {
        //载入图片,保存透明度像素点
        if(w != 0 || h != 0) _pix = _pix.scaled(w,h); //设置缩放
        QImage img = _pix.toImage();
        _vec_alpha.resize(img.width());
        for(int w=0;w<img.width();w++)
        {
            _vec_alpha[w].resize(img.height());
            for(int h=0;h<img.height();h++)
            {
                _vec_alpha[w][h] = img.pixelColor(w, h).alpha();
            }
        }
        this->resize(img.size()); //重置大小到图片尺寸
    }
    return _load_pic;
}

void qbutt_col::set_col_foreground(status col)
{
    _paint_fore = true;
    _fore = col;
    ch_col_point(_fore.normal,_back.normal);
}

void qbutt_col::set_col_background(status col)
{
    _paint_back = true;
    _back = col;
    ch_col_point(_fore.normal,_back.normal);
}

void qbutt_col::set_keep_col(bool keep)
{
    _keep_col = keep;
}

void qbutt_col::set_frame(bool frame,QPen pen)
{
    _paint_frame = frame;
    _pen_frame = pen;
}

void qbutt_col::paintEvent(QPaintEvent *event)
{
    if(_load_pic)
    {
        QPainter *show = new QPainter(this);
        show->drawPixmap(0,0,_pix);

        if(_paint_frame)
        {
            show->setPen(_pen_frame);
            show->drawRect(this->rect());
        }
        show->end();
    }
    else QWidget::paintEvent(event);
}

void qbutt_col::enterEvent(QEvent *event)
{
    ch_col_point(_fore.enter,_back.enter);
    QWidget::enterEvent(event);
}

void qbutt_col::mousePressEvent(QMouseEvent *event)
{
    ch_col_point(_fore.press,_back.press);
    QWidget::mousePressEvent(event);
}

void qbutt_col::leaveEvent(QEvent *event)
{
    if(_keep_col == false) { ch_col_point(_fore.normal,_back.normal); }
    QWidget::leaveEvent(event);
}

void qbutt_col::mouseReleaseEvent(QMouseEvent *event)
{
    if(this->rect().contains(event->pos())) { emit sn_clicked(); }
    ch_col_point(_fore.enter,_back.enter);
    QWidget::mouseReleaseEvent(event);
}

void qbutt_col::ch_col_point(QColor col_fore,QColor col_back)
{
    if(_paint_fore == false) return;
    QImage img = _pix.toImage(); //载入
    for (int w=0;w<img.width();w++)
    {
        for (int h=0;h<img.height();h++)
        {
            if(_vec_alpha[w][h] > 0 && _paint_fore)
            {
                col_fore.setAlpha(_vec_alpha[w][h]);
                img.setPixelColor(w,h,col_fore);
            }
            else if(_paint_back) { img.setPixelColor(w,h,col_back); }
        }
    }
    _pix = QPixmap::fromImage(img); //保存
    this->update();
}

== 测试图片 ==

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值