我想用样式表定制QProgressBar的外观。我想给它那种动感的,“不确定”的外观。所以我做了一个动画的GIF,放在QProgressBar::chunk的背景中。
它显示得很好,但图像是静态的,没有动画。有什么建议或变通方法吗?
我在OSX10.8上运行PyQt 4.9.4。
发布于 2012-08-11 04:10:09
所以,这是你面临的一个稍微复杂的问题。
QProgressBar依赖于来自循环或某个确定数量的信息来表示完成百分比。当您通过代码设置该值时,Qt将设置进度条的值,并重新绘制它,从而显示更新后的值。这实际上需要在您的循环中进行几毫秒的处理。如果你不这样做,那么Qt的优化将永远不会重绘。这是同步的。
你想要的“不确定”的外观(像AJAX gif旋转器或bar)被用在web上,因为进程实际上移出了客户端,在服务器上被处理并等待响应。客户端的进程完全不会被阻塞,因此可以自由地使用电影更新界面。
您可以通过在QLabel中使用QMovie来实现您想要的外观:
movie = QMovie()
movie.setFileName('/path/to/ajax_loader.gif')
movie.start()
label = QLabel(parent)
label.setMovie(movie)这将使您的不确定微调。但是,只有在事件循环处理事件时,它才会播放。一旦启动了实际的工作进程,它就会阻塞事件循环,这样电影就可以开始播放了。
你需要将事件“注入”到你的循环中的播放器中,才能让它更新。您可以通过以下方式完成此操作:
app = QApplication.instance()
# show my label
label.show()
for obj in objs:
# process stuff on my obj
app.processEvents()
# hide the label
label.hide()当然,取决于您在循环中执行的每个单独操作所花费的时间,您的旋转/加载器电影将被“卡住”,直到事件被再次处理。
实际上,实现你想要的外观的最好方法是使用线程应用程序。您可以使用QThread执行所有操作,并在处理过程中向用户显示加载器图像。这更类似于ajax的工作方式-主Qt事件循环将在您的工作线程处理所有事务时继续运行-在未知的时间量内。这是异步的。
类似于:
class MyThread(QThread):
def run( self ):
# perform some actions
...
class MyDialog(QDialog):
def __init__( self, parent ):
# initialize the dialog
...
self._thread = MyThread(self)
self._thread.finished.connect(self.refreshResults)
self.refresh()
def refresh( self ):
# show the ajax spinner
self._ajaxLabel.show()
# start the thread and wait for the results
self._thread.start()
def refreshResults( self ):
# hide the ajax spinner
self._ajaxLabel.hide()
# process the thread results
...我有一个加载器小部件,每当我在GUI库中做这样的事情时,我都会使用它。如果你想看它的代码/使用它,它在http://dev.projexsoftware.com/projects/projexui,类是XLoaderWidget (projexui.widgets.xloaderwidget)
设置与上面相同,但只需:
from projexui.widgets.xloaderwidget import XLoaderWidget
class MyThread(QThread):
def run( self ):
# perform some actions
...
class MyDialog(QDialog):
def __init__( self, parent ):
# initialize the dialog
...
self._thread = MyThread(self)
self._thread.finished.connect(self.refreshResults)
self.refresh()
def refresh( self ):
# show the ajax spinner
XLoaderWidget.start(self)
# start the thread and wait for the results
self._thread.start()
def refreshResults( self ):
# hide the ajax spinner
XLoaderWidget.stop(self)
# process the thread results
...https://stackoverflow.com/questions/11873372
复制相似问题