我尝试使用样式表制作自定义 QPushButton。当我们将鼠标悬停在按钮上时,我想自定义按钮的颜色。它有效,但我想设置一个过渡持续时间。
但在 Qt 中,此选项不可用。

这是我的自定义按钮:

#include "bouton.h"

Bouton::Bouton(QString title, QWidget *parent) : QPushButton()
{
  setGeometry(50,50,120,40);
  setText(title);
  setMinimumHeight(30);
  setParent(parent);
  setStyleSheet(" QPushButton {"
              "border-radius: 5px; "
              "border: 1.5px solid rgb(91,231,255); "
              "background-color: white; }"
              "QPushButton:pressed {"
              "border: 1.4px solid rgb(73,186,205); }"
              "QPushButton:hover {"
              "font-size: 16px;"
              "transition: 0.9s; }");
}

“过渡 0.9 秒”的论点不起作用。

这是一个 example in CSS

还有其他方法可以做到这一点吗?

最佳答案

原因

QSS 不是 CSS。没有过渡属性。 Here 是所有可用属性的列表。

解决方案

我建议您不要使用样式表,而是走另一条路,这条路更长,但为您提供了更大的灵活性。这是解决方案:

  • 创建 QPushButton 的子类,例如AnimatedHoverButton
  • 通过重新实现 QEvent::HoverEnter 获取有关 QEvent::HoverLeaveQPushButton::event events 的通知
    bool AnimatedHoverButton::event(QEvent *event)
    {
        switch (event->type()) {
        case QEvent::HoverEnter:
            animateHover(true);
            break;
        case QEvent::HoverLeave:
            animateHover(false);
            break;
        }
    
        return QPushButton::event(event);
    }
    
  • 使用 in 创建 outQVariantAnimation 转换
    void AnimatedHoverButton::animateHover(bool in)
    {
        const QColor &baseColor(palette().brush(QPalette::Button).color());
        const QColor &highlightColor(palette().brush(QPalette::Highlight).color());
        QColor startValue(in ? baseColor : highlightColor);
    
        if (m_transition) {
            startValue = m_transition->currentValue().value<QColor>();
            m_transition->stop();
        }
    
        m_transition = new QVariantAnimation(this);
    
        m_transition->setStartValue(startValue);
        m_transition->setEndValue(in ? highlightColor : baseColor);
        m_transition->setDuration(m_duration);
    
        connect(m_transition, &QVariantAnimation::valueChanged, [this](const QVariant &value){
            m_currentColor = value.value<QColor>();
            repaint();
        });
    
        connect(m_transition, &QVariantAnimation::destroyed, [this](){
            m_transition = nullptr;
        });
    
        m_transition->start(QAbstractAnimation::DeleteWhenStopped);
    }
    
  • 通过重新实现 QPushButton::paintEvent 事件处理程序并考虑动画的当前值来绘制按钮
    void AnimatedHoverButton::paintEvent(QPaintEvent * /*event*/)
    {
        QStylePainter painter(this);
        QStyleOptionButton option;
        QPalette p(palette());
    
        initStyleOption(&option);
    
        p.setBrush(QPalette::Button, m_currentColor);
    
        option.palette = p;
        option.state |= QStyle::State_MouseOver;
    
        painter.drawControl(QStyle::CE_PushButton, option);
    }
    

  • 注意: 此解决方案使用小部件的调色板来设置动画的开始和结束值。

    例子

    解决方案可能看起来很复杂,但幸运的是,我为您准备了一个关于如何实现和使用 AnimatedHoverButton 类的工作示例。

    以下代码片段使用 AnimatedHoverButton 类来生成结果,类似于您提供的 CSS 示例:
    auto *button = new AnimatedHoverButton(tr("Hover Over Me"), this);
    
    QPalette p(button->palette());
    
    p.setBrush(QPalette::Button, QColor("#F89778"));
    p.setBrush(QPalette::ButtonText, QColor("#FFFFFF"));
    p.setBrush(QPalette::Highlight, QColor("#F4511E"));
    
    button->setPalette(p);
    button->setTransitionDuration(300);
    
    setCentralWidget(button);
    setContentsMargins(10, 10, 10, 10);
    

    该示例的完整代码可在 GitHub 上找到。

    结果

    给定的示例产生以下结果:

    c&#43;&#43; - 如何向 QPushButton 添加悬停过渡?-LMLPHP

    关于c++ - 如何向 QPushButton 添加悬停过渡?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53084981/

    10-13 01:40