Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set animated icon to QPushButton in Qt5?

Tags:

QPushButton can have icon, but I need to set animated icon to it. How to do this? I created new class implemented from QPushButton but how to replace icon from QIcon to QMovie?

like image 629
Robotex Avatar asked Mar 12 '13 23:03

Robotex


2 Answers

This can be accomplished without subclassing QPushButton by simply using the signal / slot mechanism of Qt. Connect the frameChanged signal of QMovie to a custom slot in the class that contains this QPushButton. This function will apply the current frame of the QMovie as the icon of the QPushButton. It should look something like this:

// member function that catches the frameChanged signal of the QMovie void MyWidget::setButtonIcon(int frame) {     myPushButton->setIcon(QIcon(myMovie->currentPixmap())); } 

And when allocating your QMovie and QPushButton members ...

myPushButton = new QPushButton(); myMovie = new QMovie("someAnimation.gif");  connect(myMovie,SIGNAL(frameChanged(int)),this,SLOT(setButtonIcon(int)));  // if movie doesn't loop forever, force it to. if (myMovie->loopCount() != -1)     connect(myMovie,SIGNAL(finished()),myMovie,SLOT(start()));  myMovie->start(); 
like image 90
Sir Digby Chicken Caesar Avatar answered Sep 29 '22 09:09

Sir Digby Chicken Caesar


Since I had to solve this problem for a project of mine today, I just wanted to drop the solution I found for future people, because this question has lots of views and I considered the solution quite elegant. The solution was posted here. It sets the icon of the pushButton every time, the frame of the QMovie changes:

auto movie = new QMovie(this); movie->setFileName(":/sample.gif"); connect(movie, &QMovie::frameChanged, [=]{   pushButton->setIcon(movie->currentPixmap()); }); movie->start(); 

This also has the advantage, that the icon will not appear, until the QMovie was started. Here is also the python solution, I derived for my project:

#'hide' the icon on the pushButton pushButton.setIcon(QIcon()) animated_spinner = QtGui.QMovie(":/icons/images/loader.gif") animated_spinner.frameChanged.connect(updateSpinnerAniamation)             def updateSpinnerAniamation(self):   #'hide' the text of the button   pushButton.setText("")   pushButton.setIcon(QtGui.QIcon(animated_spinner.currentPixmap())) 

Once you want to show the spinner, just start the QMovie:

animated_spinner.start() 

If the spinner should disappear again, then stop the animation and 'hide' the spinner again. Once the animation is stopped, the frameChanged slot won't update the button anymore.

animated_spinner.stop() pushButton.setIcon(QtGui.QIcon()) 
like image 21
captainmoron Avatar answered Sep 29 '22 09:09

captainmoron