21

QPushButton可以有图标,但我需要为其设置动画图标。这该怎么做?我创建了实现的新类,QPushButton但如何将图标替换QIconQMovie

4

2 回答 2

29

这可以QPushButton通过简单地使用 Qt 的信号/槽机制来完成,而无需子类化。frameChanged将 的信号连接QMovie到包含 this 的类中的自定义插槽QPushButton。此函数将应用当前帧QMovie作为 的图标QPushButton。它应该看起来像这样:

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

在分配您QMovieQPushButton成员时...

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();
于 2013-03-13T04:34:30.880 回答
3

由于我今天必须为我的一个项目解决这个问题,所以我只想放弃我为未来的人找到的解决方案,因为这个问题有很多观点,我认为该解决方案非常优雅。解决方案已发布here。每次设置 pushButton 的图标,QMovie 的帧都会改变:

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

这还有一个优点,就是图标不会出现,直到 QMovie 启动。这也是我为我的项目派生的python解决方案:

#'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()))

一旦你想显示微调器,只需启动 QMovie:

animated_spinner.start()

如果微调器应该再次消失,则停止动画并再次“隐藏”微调器。一旦动画停止,frameChanged 插槽将不再更新按钮。

animated_spinner.stop()
pushButton.setIcon(QtGui.QIcon())
于 2020-12-15T17:30:30.910 回答