使用QT自定义了一个ToolBox抽屉动画

 

使用QT实现一个自定义的ToolBox,做了一个展开和收缩的动画效果,目前是500ms延时,基于之前的代码做了些修改,参考了已写其它资料,目前测试效果还算良好,不过是demo版,使用需要自己移植和改造,上代码:

 

AnimationToolBox.h

#include <QWidget>
#include <QMap>
#include "publiclibrary.h"

class QLayout;
class QScrollArea;
class AnimationToolPage;
class PLUGINSSHARED_EXPORT AnimationToolBox : public QWidget
{
    Q_OBJECT
public:
    explicit AnimationToolBox(QWidget *parent = nullptr);
    AnimationToolBox(const QString &name, QWidget *parent = NULL);
    virtual ~AnimationToolBox();
    void addWidget(const QString &title, QWidget *widget);
    void setActions(const QStringList &titleList);

signals:

public slots:

private:
    void initialize();

private:
    QString m_strToolBoxName;
    QMap<QString, AnimationToolPage*> m_mapToolPage;
    QScrollArea *m_scrollArea;
    QLayout *m_layout;
    Qt::Orientations m_ori;
};

AnimationToolBox.cpp

#include "animationtoolbox.h"
#include <QGridLayout>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QScrollArea>
#include "animationtoolpage.h"

AnimationToolBox::AnimationToolBox(QWidget *parent)
    : QWidget(parent)
    , m_strToolBoxName("")
    , m_ori(Qt::Vertical)
{
    initialize();
}

AnimationToolBox::AnimationToolBox(const QString &name, QWidget *parent)
    : QWidget(parent)
    , m_strToolBoxName(name)
    , m_ori(Qt::Vertical)
{
    initialize();
}

AnimationToolBox::~AnimationToolBox()
{

}

void AnimationToolBox::addWidget(const QString &title, QWidget *widget)
{
    AnimationToolPage *page = NULL;
    if(m_mapToolPage.contains(title))
    {
        page = m_mapToolPage.value(title);
    }
    if(NULL == page)
    {
        page = new AnimationToolPage(title, this);
    }
    page->setMinimumHeight(40);
    page->addPage(title, widget);
    m_layout->addWidget(page);
}

void AnimationToolBox::setActions(const QStringList &titleList)
{
    foreach (QString title, titleList)
    {
        addWidget(title, new QWidget);
    }
}

void AnimationToolBox::initialize()
{
    QGridLayout *gridLayout = new QGridLayout(this);
    gridLayout->setSpacing(0);
    gridLayout->setObjectName(QStringLiteral("gridLayout"));
    gridLayout->setContentsMargins(0, 0, 0, 0);

    m_scrollArea = new QScrollArea(this);
    m_scrollArea->setObjectName(QStringLiteral("scrollArea"));
    m_scrollArea->setWidgetResizable(true);

    QWidget *widget = new QWidget(this);
    if(m_ori == Qt::Vertical)   //暂时只实现垂直布局
    {
        m_layout = new QVBoxLayout;
    }
    else
    {
        m_layout = new QHBoxLayout;
    }
    m_layout->setContentsMargins(0, 0, 0, 0);
    m_layout->setSpacing(0);

    QVBoxLayout *vBoxLayout = new QVBoxLayout(widget);
    vBoxLayout->setContentsMargins(0, 0, 0, 0);
    vBoxLayout->addLayout(m_layout);
    vBoxLayout->addStretch(1);

    m_scrollArea->setWidget(widget);
    gridLayout->addWidget(m_scrollArea, 0, 0, 1, 1);
}

AnimationToolPage.h

#include <QWidget>

class QStackedWidget;
class AnimationToolPage : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(int fixValue READ fixValue WRITE setFixValue/* NOTIFY fixHeightChanged*/)
public:
    explicit AnimationToolPage(QWidget *parent = nullptr);
    AnimationToolPage(const QString &name, QWidget *parent = NULL);
    virtual ~AnimationToolPage();
    void addPage(const QString &name, QWidget *page);
    int fixValue() const;
    void setFixValue(const int &value);

//signals:

public slots:
    void slotBtnClicked(const QString& name, const int&type, const int&state);

private:
    void initialize();

private:
    QString m_strName;
    QString m_childName;
    QWidget *m_childWidget;
    QWidget *m_pButton;
    Qt::Orientations m_ori;
    QStackedWidget *m_contantWidget;
    int m_nFixHeight;
    int m_nMaxHeight;
};

AnimationToolPage.cpp

此文件做了些修改,上个版本,折叠会button会闪,改造了一下,目前测试还算ok,需要横向的需要自己手动增加了

#include "animationtoolpage.h"
#include "button/checkboxlabelbutton.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QStackedWidget>
#include <QPropertyAnimation>
#include "publicdefine.h"

AnimationToolPage::AnimationToolPage(QWidget *parent)
    : QWidget(parent)
    , m_strName("toolpage")
    , m_childName("")
    , m_childWidget(NULL)
    , m_pButton(NULL)
    , m_contantWidget(NULL)
    , m_nFixHeight(0)
    , m_nMaxHeight(200)
    , m_ori(Qt::Vertical)
{
    initialize();
}

AnimationToolPage::AnimationToolPage(const QString &name, QWidget *parent)
    : QWidget(parent)
    , m_strName(name)
    , m_childName("")
    , m_childWidget(NULL)
    , m_pButton(NULL)
    , m_contantWidget(NULL)
    , m_nFixHeight(0)
    , m_nMaxHeight(200)
    , m_ori(Qt::Vertical)
{
    initialize();
}

AnimationToolPage::~AnimationToolPage()
{

}

void AnimationToolPage::addPage(const QString &name, QWidget *page)
{
    m_childName = name;
    if(NULL == page)
    {
        SAFE_DELETE(m_contantWidget);
        return;
    }
    m_nMaxHeight = page->height();
    m_contantWidget->addWidget(page);
}

int AnimationToolPage::fixValue() const
{
    return m_nFixHeight;
}

void AnimationToolPage::setFixValue(const int &value)
{
    m_nFixHeight = value;
    if(Qt::Vertical == m_ori)
    {
        this->setFixedHeight(value);
    }
    else
    {
        this->setFixedWidth(value);
    }
}

void AnimationToolPage::slotBtnClicked(const QString &name, const int &type, const int &state)
{
    //复选框(暂时不实现)
    if(type == CheckBoxLabelButton::CheckBox)
    {
        return;
    }
    //创建动画
    QPropertyAnimation *pAnimation = new QPropertyAnimation(this, "fixValue");
    pAnimation->setDuration(500);
    bool bHide = false;
    if(state == CheckBoxLabelButton::Collapse)//折叠
    {
        bHide = true;
        pAnimation->setStartValue(m_nMaxHeight);
        pAnimation->setEndValue(40);
    }
    else//展开
    {
        m_contantWidget->show();
        pAnimation->setStartValue(40);
        pAnimation->setEndValue(m_nMaxHeight);
    }
    pAnimation->start(QAbstractAnimation::DeleteWhenStopped);
    if(bHide)
    {
        connect(pAnimation, &QPropertyAnimation::finished, [=](){
            m_contantWidget->hide();
        });
    }
}

void AnimationToolPage::initialize()
{
    if(NULL == m_pButton)
    {
        CheckBoxLabelButton *pBtn = new CheckBoxLabelButton(m_strName, this);
        pBtn->setMinimumHeight(40);
        pBtn->setBtnName(m_strName, CheckBoxLabelButton::Button);
        pBtn->setHidden();
        connect(pBtn, &CheckBoxLabelButton::sigBtnClicked,
                this, &AnimationToolPage::slotBtnClicked);
        m_pButton = pBtn;
        pBtn->setStyleSheet("background-color:rgb(128,128,128);");
    }
    if(!m_contantWidget)
    {
        m_contantWidget = new QStackedWidget(this);
    }
    //目前仅实现垂直方向
    QVBoxLayout *vLayout = new QVBoxLayout(this);
    vLayout->setSpacing(0);
    vLayout->setContentsMargins(0, 0, 0, 0);
    vLayout->addWidget(m_pButton);
    vLayout->addWidget(m_contantWidget);
    this->setLayout(vLayout);
    this->setFixedHeight(40);
    m_contantWidget->hide();
}

应用:

AnimationToolBox *pToolBox = new AnimationToolBox(this);
QLabel *pLabel = new QLabel("test");
pLabel->setStyleSheet("background-color:rgb(255,255,255)");
pToolBox->addWidget("test", pLabel);
pLabel = new QLabel("test1");
pLabel->setStyleSheet("background-color:rgb(255,255,255)");
pToolBox->addWidget("test1", pLabel);
ui->verticalLayout->addWidget(pToolBox);

还有一个button的代码就没粘贴了,就是实现一个button,点击信号判断是折叠还是展开就可以了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值