Qt自定义Button组控件

Qt自定义Button组控件

简述

在网上也看到大佬们实现过这样的效果,然后自己也想想封装了一套。下划线带动画效果。
封装类包括:
1.设置按钮位置,分东南西北方向
void setButtonPosition(int position);
2.下划线颜色
void setButtonColor(QColor color);
3.下划线的高度
void setLineHeight(int lineHeight);

效果图

这里写图片描述

代码篇

CusButtonGroup::CusButtonGroup(QWidget *parent)
    : QWidget(parent)
    , m_btnPosition(0)
    , m_curIndex(0)
    , m_preIndex(0)
    , m_offset(0)
    , m_lineHeight(2)
    , m_lineColor(QColor(21, 156, 119))
{
    ui.setupUi(this);
    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    m_btnGroup = new QButtonGroup(this);
    connect(m_btnGroup, SIGNAL(buttonClicked(int)), SLOT(onbuttonClicked(int)));

    m_animation = new QPropertyAnimation(this, "");
    m_animation->setDuration(200);
    connect(m_animation, SIGNAL(valueChanged(QVariant)), SLOT(onvalueChanged(QVariant)));

    //默认在上边
    setButtonPosition(CusButtonGroup::North);
}

CusButtonGroup::~CusButtonGroup()
{

}

void CusButtonGroup::onvalueChanged(QVariant variant)
{
    m_offset = variant.toInt();
    update();
}

void CusButtonGroup::setLineHeight(int lineHeight)
{
    m_lineHeight = lineHeight;
}

void CusButtonGroup::paintEvent(QPaintEvent *event)
{
    QWidget::paintEvent(event);
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing);
    painter.setPen(Qt::NoPen);
    painter.setBrush(m_lineColor);
    if (m_btnPosition == CusButtonGroup::North)
    {
        painter.drawRect(m_offset, 0, m_btnSize.width(), m_lineHeight);
    }
    else if (m_btnPosition == CusButtonGroup::South)
    {
        painter.drawRect(m_offset, this->height() - m_lineHeight, m_btnSize.width(), m_lineHeight);
    }
    else if (m_btnPosition == CusButtonGroup::West)
    {
        painter.drawRect(0, m_offset, m_lineHeight, m_btnSize.height());
    }
    else if (m_btnPosition == CusButtonGroup::East)
    {
        painter.drawRect(this->width() - m_lineHeight, m_offset, m_lineHeight, m_btnSize.height());
    }
}

void CusButtonGroup::setButtonPosition(int position)
{
    deleteLayout();
    m_btnPosition = position;
    if (position == CusButtonGroup::North)
    {
        QHBoxLayout* layout = new QHBoxLayout(this);
        layout->setContentsMargins(0, m_lineHeight, 0, 0);
        layout->setSpacing(0);
        setLayout(layout);
    }
    else if (position == CusButtonGroup::South)
    {
        QHBoxLayout* layout = new QHBoxLayout(this);
        layout->setContentsMargins(0, 0, 0, m_lineHeight);
        layout->setSpacing(0);
        setLayout(layout);
    }
    else if (position == CusButtonGroup::West)
    {
        QVBoxLayout* layout = new QVBoxLayout(this);
        layout->setContentsMargins(m_lineHeight, 0, 0, 0);
        layout->setSpacing(0);
        setLayout(layout);
    }
    else if (position == CusButtonGroup::East)
    {
        QVBoxLayout* layout = new QVBoxLayout(this);
        layout->setContentsMargins(0, 0, m_lineHeight, 0);
        layout->setSpacing(0);
        setLayout(layout);
    }
    else
    {
        Q_ASSERT(false && "no match position!");
    }
}

void CusButtonGroup::addButton(QPushButton* btn, int id)
{
    m_btnGroup->addButton(btn, id);
    m_buttonLst.append(btn);
    layout()->addWidget(btn);
    m_btnSize = btn->size();

    QString style = QString("QPushButton{background-color:#ffffff;border:none;}"
        "QPushButton:hover{background-color:rgba(%1, %2, %3, 40);}"
        "QPushButton:pressed, QPushButton:checked{background-color:rgba(%1, %2, %3, 80);}").arg(m_lineColor.red()).arg(m_lineColor.green()).arg(m_lineColor.blue());

    btn->setStyleSheet(style);
}

void CusButtonGroup::setButtonColor(QColor color)
{
    m_lineColor = color;
}

void CusButtonGroup::onbuttonClicked(int index)
{
    m_btnGroup->button(index)->setChecked(true);
    m_preIndex = m_curIndex;
    m_curIndex = index;
    if (m_btnPosition == CusButtonGroup::North || m_btnPosition == CusButtonGroup::South)
    {
        m_animation->setStartValue(m_preIndex * m_btnSize.width());
        m_animation->setEndValue(index * m_btnSize.width());
    }
    else if (m_btnPosition == CusButtonGroup::West || m_btnPosition == CusButtonGroup::East)
    {
        m_animation->setStartValue(m_preIndex * m_btnSize.height());
        m_animation->setEndValue(index * m_btnSize.height());
    }
    m_animation->start();
}

void CusButtonGroup::deleteLayout()
{
    //清除布局,包括布局内控件
    if (this->layout() != nullptr)
    {
        QLayoutItem *child;
        while ((child = this->layout()->takeAt(0)) != 0) {
            delete child->widget();
            delete child;
            child = nullptr;
        }
        m_buttonLst.clear();
        delete this->layout();
        this->setLayout(nullptr);
    }
}

封装类的用法例子

//下划线高度默认2像素,颜色也是默认,位置默认在北方
    CusButtonGroup w4;
    //设置下划线颜色
    w4.setButtonColor(QColor(255, 163, 69));
    //设置下划线高度
    w4.setLineHeight(4);
    //设置下划线高度
    w4.setButtonPosition(CusButtonGroup::East);
    for (int index = 0; index < 6; ++index)
    {
        QPushButton *btn = new QPushButton;
        btn->setCheckable(true);
        btn->setText(QString("Button_%1").arg(index));
        btn->setFixedSize(80,32);
        w4.addButton(btn, index);
    }

结尾

博主这么多博客中,觉得不错,还可以的。可以考虑打赏下博主。不断为大家开源更多精彩内容,谢谢大家支持~

这里写图片描述

这里写图片描述

猜你喜欢

转载自blog.csdn.net/ly305750665/article/details/80736504