2010-10-17 2 views
3

Je veux réduire progressivement l'opacité d'un QPushButton sur une période de 2 secondes pour compléter la transparence. Pour cela, j'ai utilisé la classe QPropertyAnimation et utilisé la propriété "windowOpacity" du bouton pour obtenir l'effet. Mais cela ne fonctionnait que pour un QPushButton autonome. Lorsque j'ai affecté un parent au bouton, l'effet a disparu. Y a-t-il un moyen d'obtenir le même effet pour les boutons enfants?qt: Comment animer la transparence d'un enfant QPushButton en utilisant QPropertyAnimation?

Répondre

14

La propriété windowOpacity s'applique uniquement aux fenêtres de niveau supérieur, ce qui ne vous aidera malheureusement pas à animer la transparence des widgets enfants.

Les contrôles standard sont un peu problématiques et de nombreuses considérations contribuent à leur apparence finale. Il y a beaucoup d'approches que vous pourriez prendre, mais elles impliqueront toutes une certaine quantité de codage. Il n'y a pas de manière simple :)

Pour définir la transparence d'un QPushButton, vous devez définir une feuille de style ou modifier certaines des propriétés de la palette. Aucune de ces options n'étant directement utilisable par un QPropertyAnimation, vous pouvez créer votre propre propriété personnalisée et l'animer. Voici un code qui spécifie une propriété personnalisée pour un MainWindow appelé alpha. La valeur alpha est utilisée pour définir la partie alpha de la couleur du bouton. Avec cette propriété en place, nous pouvons utiliser QPropertyAnimation pour l'animer. Le résultat est un bouton qui se fane dedans et dehors. Cela ne gère que l'arrière-plan des boutons et non le texte, mais il devrait fournir un point de départ pour vous.

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:(Mise à jour pour inclure par exemple la transparence stylesheet)

#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(); 
} 
+0

Merci beaucoup. Cela a fonctionné mais pas si j'ai mis la couleur à travers une feuille de style. Tout indice quant aux fonctions à manipuler pour rendre les bordures et le texte transparents? – Daud

+0

Tout ce dont vous avez besoin est disponible dans la documentation de QPalette. Il y en a beaucoup mais certains lisant et expérimentant avec le code que j'ai fourni vous y mèneront. C'est tout ce que j'ai fait :) –

+0

J'ai mis à jour l'exemple de code pour inclure un bouton avec une transparence basée sur une feuille de style puisque vous avez mentionné que vous ne pouviez pas le faire fonctionner. –

1

J'ai fait face au même problème il y a quelque temps et je suis arrivé à la même solution (en manipulant la palette de contrôles). Mais, bien que la propriété d'aide dans la MainWindow soit sûrement une solution rapide et facile, elle est sale aussi. Donc, au moins pour une utilisation plus importante et récurrente, il était beaucoup plus approprié de créer une nouvelle classe d'animation couvrant ces besoins. Ce n'est pas beaucoup plus de code (héritez simplement de QAbstractAnimation, déplacez cette palette et transmettez le contrôle cible en tant que paramètre dans cette classe) mais il garde votre contrôle parent (comme la classe mainwindow) libre de ces détails d'implémentation d'animation sûrement ne pas appartenir là-bas.