自定义按钮,鼠标移入、移出、摁下,分别改变按钮图标样式原理和代码总结(上图标下文字、hover、QSS样式表、QPushbutton)

本文主要总结一个自定义按钮,该按钮样式效果类似样式表的鼠标悬停(移入)、鼠标移出、鼠标摁下效果。当鼠标分别悬停(移入)、移出、摁下时,其内的图像子控件分别变为对应的图片。下面分别对实现效果进行原理讲解和代码示例。

一、原理讲解

自定义控件主要是继承QPushbutton的,其中具体的绘制和功能可以参考博主下面两篇博客:

https://blog.csdn.net/naibozhuan3744/article/details/82151007和

https://blog.csdn.net/naibozhuan3744/article/details/102536188。

本文主要讲解样式表效果的鼠标移入(悬停)、鼠标移出、鼠标摁下的效果功能。

1.1鼠标移入、移出、摁下效果

实现鼠标移入、移出、摁下效果,主要是用到事件函数,当我们鼠标进入某个控件时,系统会发送一个鼠标移入事件,我们只需要重写QWidget的鼠标移入事件虚函数enterEvent()或者重写QWidget监测所有事件虚函数event(),通过过滤鼠标移入、移出、摁下事件,编写对应的逻辑业务代码。其中,QWidget的事件函数event()原理讲解可以参考这篇别人写的优秀博客:http://mobile.51cto.com/symbian-273119.htm###。本文主要用后面一种方法,通过重写QWidget的事件虚函数event(),监听过对应的鼠标移入、移出、摁下事件,然后编写对应业务逻辑代码。

1.2事件虚函数event()主要模板总结

下面是QWidget的事件虚函数event()声明和定义,以及常用写法模板。

#include 
#include 
#include 

//声明
class QCustomButton : public QPushButton
{
protected:    
    void enterEvent();
};

//定义
bool QCustomButton::event(QEvent *e)
{
    if(this->isChecked())
        return QWidget::event(e);

    switch (e->type()) {
    case QEvent::Enter:
    {//鼠标进入事件
        //此处写逻辑代码
        //return true;
        break;
    }

    case QEvent::MouseButtonPress:
    {//鼠标摁下事件
        //此处写逻辑代码
        //return true;
        break;
    }
    case QEvent::Leave:
    {//鼠标离开事件
        //此处写逻辑代码
        //return true;
        break;
    }
    default:
        break;
    }
    return QWidget::event(e);
}

博主采用的是这种方式的原因主要是因为通用性强,这种方式不但可以监听过滤鼠标事件,还可以监听过滤其它事件,比如键盘摁下事件、硬盘插拔事件、绘图事件、比如定时器溢出事件等所有QWidget自定义的事件,都可以通过重写这个总事件虚函数event进行监听过滤。具体的QWidget所有事件枚举类型,可以参考博主这篇博客:https://blog.csdn.net/naibozhuan3744/article/details/102485019。

注意:这里重写事件函数event,不能返回true,否则原有按钮第一次单击事件会被基类忽略,而形成第一次单击无效的bug,返回QWidget::event(e)基类消息,继续处理后续基类的消息事件。

二、示例代码

2.1新建一个Widget工程,勾选UI界面

然后新加一个基类为QPushButton的类QCustomButton。其中类QCustomButton就是自定义的按钮,该按钮布局是上图片下文字,任何间距可以任意调整,同时实现了鼠标移入、移出、摁下按钮时,自定义按钮内的图片自动切换为设置的图片。

当然,调用的时候,需要手动设置鼠标移入、移出、摁下的图片路径,否则不会显示。

2.2分别在qcustombutton.h、qcustombutton.cpp、widget.h、widget.cpp、main.cpp中添加如下代码

qcustombutton.h

#ifndef QCUSTOMBUTTON_H
#define QCUSTOMBUTTON_H

#include 
#include 
#include 
#include 

class QCustomButton : public QPushButton
{
public:
    explicit QCustomButton(QWidget *parent = nullptr);
    void setImageLbl(const QPixmap &pixmap);
    void setNormalImagePath(const QPixmap &pixmap);
    void setHoverImagePath(const QPixmap &pixmap);
    void setPressedImagePath(const QPixmap &pixmap);
    void setTextLbl(QString text);
    QLabel *getImageHandle();
    QLabel *getTextHandle();

protected:
    virtual bool event(QEvent *e);    

private:
    QLabel *imageLbl;
    QLabel *textLbl;

    QPixmap hoverImage;
    QPixmap pressedImage;
    QPixmap normalImage;
};

#endif // QCUSTOMBUTTON_H

 

qcustombutton.cpp

#include 
#include 
#include 

//声明
class QCustomButton : public QPushButton
{
protected:    
    void enterEvent();
};

//定义
bool QCustomButton::event(QEvent *e)
{
    if(this->isChecked())
        return QWidget::event(e);

    switch (e->type()) {
    case QEvent::Enter:
    {//鼠标进入事件
        //此处写逻辑代码
        //return true;
        break;
    }

    case QEvent::MouseButtonPress:
    {//鼠标摁下事件
        //此处写逻辑代码
        //return true;
        break;
    }
    case QEvent::Leave:
    {//鼠标离开事件
        //此处写逻辑代码
        //return true;
        break;
    }
    default:
        break;
    }
    return QWidget::event(e);
}

 

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include 

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();



private:
    Ui::Widget *ui;

    void initUI();
};

#endif // WIDGET_H

 

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "qcustombutton.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    initUI();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::initUI()
{
    QCustomButton *customButton=new QCustomButton(this);
    customButton->setImageLbl(QPixmap(":/resource/image/base.png"));
    customButton->setNormalImagePath(QPixmap(":/resource/image/base.png"));
    customButton->setHoverImagePath(QPixmap(":/resource/image/base_hover.png"));
    customButton->setPressedImagePath(QPixmap(":/resource/image/base_pressed.png"));
    customButton->setTextLbl("我是text");
    customButton->setCheckable(true);
    customButton->setFixedSize(300,300);
    customButton->setGeometry(0,0,300,300);
//    customButton
    customButton->show();
    customButton->installEventFilter(this);
}

 

main.cpp

#include "widget.h"
#include 

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

    return a.exec();
}

2.3程序运行结果如下图所示

 

2.4总结

由上图结果可知,正常程序显示的是一个小草;当鼠标移入自定义按钮时,图片变成一只蜗牛;当鼠标摁下是图片变成一个电脑台式机;当鼠标移出时,图片再次变成一只蜗牛;实现了鼠标移入、移出、摁下选中分别切换对应图片效果。

程序运行后,出现警告:

libpng warning: iCCP: known incorrect sRGB profile
libpng warning: iCCP: known incorrect sRGB profile

经过查找原因,发现是网上随意下载的*.png图片的问题,只需要换一张正常的图片即可解决警告问题!

自定义按钮,鼠标移入、移出、摁下,分别改变按钮图标样式原理和代码总结(上图标下文字、hover、QSS样式表、QPushbutton)_第1张图片

 

参考内容:

http://mobile.51cto.com/symbian-273119.htm###(参考:QEvent原理讲解)

https://blog.csdn.net/naibozhuan3744/article/details/82154880(参考:鼠标事件:移入、摁下、释放)

https://blog.csdn.net/WangJiankun_ls/article/details/79470739(参考:解决警告libpng warning: iCCP: known incorrect sRGB profile)

你可能感兴趣的:(Qt,自定义,按钮,hover,QSS,Qt工程应用)