qt:如何使用QPropertyAnimation动画化子QPushButton的透明度?

3

我想逐渐降低QPushButton的不透明度,使其在2秒钟内完全透明。为此,我使用了QPropertyAnimation类,并使用按钮的“windowOpacity”属性来实现效果。但是,这仅适用于独立的QPushButton。当我将父级分配给该按钮时,效果消失了。是否有一种方法可以为子按钮实现相同的效果?

2个回答

14
windowOpacity属性只适用于顶级窗口,因此它无法帮助您对子部件的透明度进行动画处理。
标准控件也有一些问题,因为有许多因素会影响它们的最终外观。有许多方法可以采取,但它们都需要一定量的编码。没有简单的方法 :)
要设置QPushButton的透明度,您需要为其设置样式表或更改调色板的一些属性。由于这两个选项都不能直接被QPropertyAnimation使用,所以您可以创建自己的自定义属性并对其进行动画处理。
下面是一些指定了一个名为alphaMainWindow自定义属性的代码。Alpha值用于设置按钮颜色的Alpha部分。有了这个属性,我们就可以使用QPropertyAnimation对其进行动画处理。结果是一个淡入淡出的按钮。这只处理了按钮的背景而不是文本,但应该为您提供一个起点。 MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QWidget>
#include <QPushButton>

class MainWindow : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(int alpha READ alpha WRITE setAlpha);

public:
    MainWindow();
    virtual ~MainWindow();

private:
    int m_alpha;
    QPushButton * m_button1, *m_button2;

    int alpha() const;
    void setAlpha(const int a_alpha);
};

#endif  /* MAINWINDOW_H */

MainWindow.cpp:(已更新以包括样式表透明度示例)

#include <QPlastiqueStyle>
#include <QPropertyAnimation>

#include "MainWindow.h"

MainWindow::MainWindow() :
    m_button1(0),
    m_button2(0),
    m_alpha(255)
{
    resize(200, 200);
    QPalette windowPalette(palette());
    windowPalette.setBrush(QPalette::Background, QBrush(QColor(200, 0, 0)));
    setPalette(windowPalette);

    m_button1 = new QPushButton(this);
    m_button1->setText("Palette Transparency");
    m_button1->setAutoFillBackground(false);
    // NOTE: Changing the button background color does not work with XP Styles
    // so we need to use a style that allows it.
    m_button1->setStyle(new QPlastiqueStyle());

    m_button2 = new QPushButton(this);
    m_button2->move(0, 50);
    m_button2->setText("Stylesheet Transparency");
    m_button2->setAutoFillBackground(false);
    m_button2->setStyle(new QPlastiqueStyle());

    QPropertyAnimation *animation = new QPropertyAnimation(this, "alpha");
    animation->setDuration(1000);
    animation->setKeyValueAt(0, 255);
    animation->setKeyValueAt(0.5, 100);
    animation->setKeyValueAt(1, 255);
    animation->setLoopCount(-1);
    animation->start();
}

MainWindow::~MainWindow()
{
}

int MainWindow::alpha() const
{
    return m_alpha;
}

void MainWindow::setAlpha(const int a_alpha)
{
    m_alpha = a_alpha;

    QPalette buttonPalette(m_button1->palette());
    QColor buttonColor(buttonPalette.button().color());
    buttonColor.setAlpha(m_alpha);
    buttonPalette.setBrush(QPalette::Button, QBrush(buttonColor));
    m_button1->setPalette(buttonPalette);

    QString stylesheet("background-color: rgba(0,200,0," + QString::number(m_alpha) + ");");
    m_button2->setStyleSheet(stylesheet);

}

main.cpp:

#include <QtGui/QApplication>

#include "MainWindow.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    MainWindow m;
    m.show();

    return app.exec();
}

非常感谢。它有效,但如果我通过样式表设置颜色,则无效。有什么提示可以操作哪些函数以使边框和文本也透明? - Daud
你所需要的一切都可以在QPalette的文档中找到。虽然有很多内容,但是阅读并尝试我提供的代码就可以了解。这就是我所做的 :) - Arnold Spence
我已更新示例代码,包括一个基于样式表的透明度按钮,因为您提到您无法使其工作。 - Arnold Spence

1

我曾经遇到过同样的问题,并基本上采用了相同的解决方案(操作控件面板)。但是,虽然在MainWindow中的helper属性肯定是一种快速且简单的解决方案,但也是一种不太优雅的解决方案。因此,至少对于更大和经常出现的使用情况,创建一个涵盖这些需求的新动画类似乎更为合适。这并不需要更多的代码(只需继承QAbstractAnimation,将面板相关内容放入其中,并将目标控件作为参数传递给该类),但它可以使您的父控件(如mainwindow-class)摆脱这些动画实现细节,这些细节显然不属于那里。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接