如何在Qt5中将动画图标设置为QPushButton?

Rob*_*tex 17 icons animation qt qt5 qpushbutton

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

Sir*_*sar 24

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

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

在分配你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();
Run Code Online (Sandbox Code Playgroud)

  • 我没有找到优雅的双插槽解决方案.我更喜欢子类化QPushButton并在内部处理帧更改,并使用自定义方法`setMovie`切换图标.我认为这将更优雅和OOP一致. (3认同)

小智 6

由于我今天必须为我的一个项目解决这个问题,所以我只想为未来的人放弃我找到的解决方案,因为这个问题有很多观点,而且我认为该解决方案非常优雅。解决方案已发布在这里。每次 QMovie 的框架发生变化时,它都会设置按钮的图标:

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

这还有一个优点,即在 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()))
Run Code Online (Sandbox Code Playgroud)

一旦你想显示旋转器,只需启动 QMovie:

animated_spinner.start()
Run Code Online (Sandbox Code Playgroud)

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

animated_spinner.stop()
pushButton.setIcon(QtGui.QIcon())
Run Code Online (Sandbox Code Playgroud)