Qt学习(二)设计继承自基类的派生类

2023-05-16

在网上看到一个自定义的动画按钮很喜欢,大部分代码都是参考该博客,于是这里也学着设计了一个继承自QWidget的派生类AnimationButton。

大概思路就是重载基类QWidget里的事件(enterEvent、leaveEvent、paintEvent、mousePressEvent、mouseReleaseEvent),让鼠标进入和离开该派生类的时候能产生动画,并为其添加鼠标单击事件。

//animationbutton.h
#ifndef ANIMATIONBUTTON_H
#define ANIMATIONBUTTON_H

/*
 * Writer:sym
 * FileName:Animationbutton
 * Date:2019-8-19
 * */
#include <QtCore>
#include <QtGui>

#include <QObject>
#include <QWidget>
#include <QStackedWidget>
#include <qpainter.h>
#include <qpropertyanimation.h>
#include <qdebug.h>

class Animationbutton : public QWidget
{
    Q_OBJECT
public:
    explicit Animationbutton(QWidget *parent = nullptr);
    ~Animationbutton();

protected:
    void enterEvent(QEvent *);
    void leaveEvent(QEvent *);
    void paintEvent(QPaintEvent *);
    void mousePressEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *e);

private:
    bool enter;    //是否进入
    bool leave;    //是否离开
    int pixWidth;    //图片高度
    int pixHeight;    //图片宽度
    int oldWidth;    //图片原高度
    int oldHeight;    //图片旧高度

    QPropertyAnimation *enterAnimation;    //进入动画
    QPropertyAnimation *leaveAnimation;    //离开动画

    int targetWidth;    //目标动画宽度
    int targetHeight;    //目标动画高度
    QString text;    //显示文字
    QString image;    //图像路径

    QPoint mousePos;
    QStackedWidget *sWidget=0;
    int curi;

signals:
    //鼠标单击信号
    void clicked();

private slots:
    //进入动画
    void enterImageChanged(QVariant index);
    //离开动画
    void leaveImageChanged(QVariant index);
    //鼠标单击槽
    void mouseClicked();

public slots:
    //设置动画按钮文字
    void setText(QString text);
    //设置动画按钮图片
    void setImage(QString image);
    //设置stackwidgets
    void setStackedWidgets(QStackedWidget *stackedWidget,int i);
    //设置堆栈窗体当前页
    void setCurrentWidget();
};

#endif // ANIMATIONBUTTON_H
//animationbutton.cpp
#include "animationbutton.h"

Animationbutton::Animationbutton(QWidget *parent) : QWidget(parent)
{
    enter=true;
    leave=false;
    pixWidth=0;
    oldWidth=0;
    pixHeight=0;
    oldHeight=0;

    enterAnimation=new QPropertyAnimation(this,"");    //新建动画类进入动画
    enterAnimation->setStartValue(0);    //设置属性起始值
    enterAnimation->setEndValue(5);    //设置属性终止值
    enterAnimation->setDuration(200);    //设置动画运行时长200毫秒
    connect(enterAnimation,SIGNAL(valueChanged(QVariant)),this,SLOT(enterImageChanged(QVariant)));    //关联信号槽函数

    leaveAnimation=new QPropertyAnimation(this,"");    //新建动画类离开动画
    leaveAnimation->setStartValue(0);
    leaveAnimation->setEndValue(5);
    leaveAnimation->setDuration(200);
    connect(leaveAnimation,SIGNAL(valueChanged(QVariant)),this,SLOT(leaveImageChanged(QVariant)));

    connect(this,SIGNAL(clicked()),this,SLOT(mouseClicked()));    //关联鼠标单击事件信号槽
}

Animationbutton::~Animationbutton()
{
    delete enterAnimation;
    delete leaveAnimation;
}

void Animationbutton::enterEvent(QEvent *)
{
    enter=true;
    leave=false;
    pixWidth=oldWidth-25;
    pixHeight=oldHeight-25;
    enterAnimation->start();
}

void Animationbutton::leaveEvent(QEvent *)
{
    enter=false;
    leave=true;
    pixWidth=oldWidth;
    pixHeight=oldHeight;
    leaveAnimation->start();
}

void Animationbutton::paintEvent(QPaintEvent *)
{
    if (image.isEmpty())
    {
        return;
    }

    QPainter painter(this);    //在此窗口创建qpainter类
    painter.setRenderHint(QPainter::Antialiasing,true);    //开启反锯齿

    QPixmap pix(image);    //创建画布
    pix=pix.scaled(targetWidth,targetHeight,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);    //以目标宽高以填充模式

    if ((enter||leave)&&(!enter||!leave))
    {
        int pixX=rect().center().x()-targetWidth/2;    //获取画布位置左上角横坐标
        int pixY=rect().center().y()-targetHeight/2;    //获取画布位置左上角纵坐标
        QPoint point(pixX,pixY);    //创建画布左上角坐标
        painter.drawPixmap(point,pix);    //在窗口绘制
        painter.drawText(QRectF(0,height()-20,width(),20),Qt::AlignCenter,text);    //以居中模式将文本显示在矩形类QRECTF所定义的区域中
        //QRectF(a,b,c,d),定义一块左上角坐标(a,b)的,宽c,高d的矩形区域
    }
}

void Animationbutton::mousePressEvent(QMouseEvent *e)
{
    mousePos=QPoint(e->x(),e->y());
}

void Animationbutton::mouseReleaseEvent(QMouseEvent *e)
{
    if(mousePos==QPoint(e->x(),e->y()))
        emit clicked();
}

void Animationbutton::enterImageChanged(QVariant index)    //index定义的动画属性值
{
    int i=index.toInt();
    targetWidth=pixWidth+i*5;
    targetHeight=pixHeight+i*5;
    update();    //更新动画
}

void Animationbutton::leaveImageChanged(QVariant index)
{
    int i=index.toInt();
    targetWidth=pixWidth-i*5;
    targetHeight=pixHeight-i*5;
    update();
}

void Animationbutton::setImage(QString image)
{
    this->image=image;
    QPixmap pix(image);
    pixWidth=pix.width();
    pixHeight=pix.height();
    oldWidth=pixWidth;
    oldHeight=pixHeight;
    targetWidth=pixWidth-25;    //设置图片初始大小
    targetHeight=pixHeight-25;
    update();
}

void Animationbutton::setText(QString text)
{
    this->text=text;
    update();
}

void Animationbutton::setStackedWidgets(QStackedWidget *stackedWidget,int i)
{
    sWidget=stackedWidget;
    curi=i;
}

void Animationbutton::setCurrentWidget()
{
    if(sWidget)
    {
        sWidget->setCurrentIndex(curi);
    }
}
void Animationbutton::mouseClicked()
{
    setCurrentWidget();
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt学习(二)设计继承自基类的派生类 的相关文章

随机推荐