Используя PyQt и Qt4, это правильный способ получить throbber на вкладке QTabWidget?

У меня есть код, создающий QTabWidget из Python с использованием PyQt4. Я хочу получить на вкладке анимированный gif «throbber». /Единственный способ/, который я нашел, - это следующий запутанный метод.

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)

Вызов отладки всегда возвращает true, но пульсометр иногда работает, иногда пуст, а иногда имеет большую уродливую задержку между кадрами. В частности, я не могу не думать, что подключение сигнала frameChanged из фильма к функции, которая просто вызывает jumpToFrame для того же фильма, неправильно.

Еще более огорчительно, если я просто отбрасываю лямбду (то есть заставляю строку говорить QtCore.QObject.connect(movie, QtCore.SIGNAL("frameChanged(int)"), movie.jumpToFrame), она никогда не отображает даже первый кадр.

Итак, что я делаю неправильно?

PS: я понимаю, что .tabBar() является защищенным членом, но я предположил (по-видимому, правильно), что PyQt снимает защиту с защищенных членов :). Я новичок в Qt, и я бы предпочел не подкласс QTabWidget, если я могу помочь.


person EB.    schedule 21.07.2010    source источник


Ответы (2)


Я считаю, что проблема с кодом, который я первоначально опубликовал, заключалась в том, что у QMovie не было родителя, и, таким образом, проблемы с областью действия позволили устранить основную проблему C++. Также возможно, что у меня были проблемы с потоками - threading.thread и QThread не работают вместе. Рабочий код, который у меня есть сейчас, приведен ниже - не нужно возиться с сигналами или слотами.

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)
person EB.    schedule 19.11.2010

Я столкнулся с той же проблемой, и это сообщение помогло заставить ее работать: http://www.daniweb.com/forums/printthread.php?t=191210&pp=40

Для меня это имеет значение: QMovie("image.gif", QByteArray(), self)

person Arvid Requate    schedule 18.11.2010
comment
Действительно, в вашем случае это тоже была родительская проблема. Аргумент self является родителем виджета C++ - без него объект C++ умрет после возврата вашего метода. С ним он умрет только тогда, когда объект С++ 'self' будет прикреплен к умирает. Я обнаружил, что лучше притвориться, что вы работаете на C++ для большей части работы с PyQt, и просто использовать python для более приятного синтаксиса :) - person EB.; 19.11.2010