Question

I have some code creating a QTabWidget from Python using PyQt4. I want to get a 'throbber' animated gif in the tab. The /only way/ I have found how to do this is the following convoluted method.

tabBar = self.tabReports.tabBar()
lbl = QtGui.QLabel(self.tabReports)
movie = QtGui.QMovie(os.path.join(self.basedir, "images\\throbber.gif"))
lbl.setMovie(movie)
QtCore.QObject.connect(movie, QtCore.SIGNAL("frameChanged(int)"), lambda i: movie.jumpToFrame(i))
movie.start()
log.debug("valid = %s"%(movie.isValid()))
tabBar.setTabButton(idxtab, QtGui.QTabBar.LeftSide, lbl)

The debugging call always returns true, but the throbber sometimes works, sometimes is blank, and sometimes has a large ugly delay between frames. In particular, I can't help but think connecting the frameChanged signal from the movie to a function that simply calls jumpToFrame on the same movie is not correct.

Even more distressing, if I simply drop the lambda (That is, make the line say QtCore.QObject.connect(movie, QtCore.SIGNAL("frameChanged(int)"), movie.jumpToFrame) it never renders even the first frame.

So, what am I doing wrong?

PS: I realize .tabBar() is a protected member, but I assumed (apparently correctly) that PyQt unprotects protected members :). I'm new to Qt, and i'd rather not subclass QTabWidget if I can help it.

Was it helpful?

Solution

I believe the problem with the code I initially posted was that the QMovie didn't have a parent, and thus scoping issues allowed the underlying C++ issue to be destroyed. It is also possible I had had threading issues - threading.thread and QThread do not play nice together. The working code I have now is below - no messing with signals nor slots needed.

def animateTab(self, tab_widget, enable):
    tw = tab_widget
    tabBar = tw.tabBar()
    if enable:
        lbl = QtGui.QLabel(tw)
        movie = QtGui.QMovie("images\\throbber.gif"), parent=lbl)
        movie.setScaledSize(QtCore.QSize(16, 16))
        lbl.setMovie(movie)
        movie.start()
    else:
        lbl = QtGui.QLabel(tw)
        lbl.setMinimumSize(QtCore.QSize(16, 16))
    tabBar.setTabButton(tab_section.index, QtGui.QTabBar.LeftSide, lbl)

OTHER TIPS

I faced the same problem and this posting helped to make it work: http://www.daniweb.com/forums/printthread.php?t=191210&pp=40

For me this seems to make the difference: QMovie("image.gif", QByteArray(), self)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top