我想用樣式表自定義QProgressBar的外觀。我想給它那動畫,'不確定'的樣子。所以我製作了一個動畫GIF,以保留QProgressBar::chunk
的背景。QStyleSheet中的靜態Gif動畫
它顯示正常,但圖像是靜態的,沒有動畫。任何建議或解決方法?
我在OS X 10.8上運行PyQt 4.9.4。
我想用樣式表自定義QProgressBar的外觀。我想給它那動畫,'不確定'的樣子。所以我製作了一個動畫GIF,以保留QProgressBar::chunk
的背景。QStyleSheet中的靜態Gif動畫
它顯示正常,但圖像是靜態的,沒有動畫。任何建議或解決方法?
我在OS X 10.8上運行PyQt 4.9.4。
所以,這是一個稍微複雜的問題,你正面臨着。
QProgressBar依賴來自循環或某個確定數量的信息來表示完成百分比。當您通過代碼設置值時,Qt將設置進度條的值,重繪它並顯示更新後的值。這實際上在循環中需要幾毫秒的處理。如果你沒有這樣做,那麼Qt的優化不會重繪。這是同步的。
Web上使用了「不確定」外觀(如AJAX GIF微調控制器或欄),因爲該過程實際上已從客戶端移出,並且正在服務器上處理,並且正在等待響應。客戶端的進程根本沒有被阻止,所以可以隨電影更新界面。
你可以實現你通過在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
...
多好的回答,@Eric!感謝您深入細節。我會將此標記爲正確的答案,因爲我認爲這將對大多數人有幫助。在我的確切情況下,我已經有一個異步過程來更新我的酒吧的進度。我想將動畫GIF作爲進度條的完成部分的背景,以便爲連續工作提供視覺印象。然而,也許一個小巧的,循環的QMovie在酒吧一側將會同樣有效。謝謝! – splodingsocks 2012-08-11 20:57:18
哦,我明白了......我誤解了這個問題......那樣的話,我真的不知道答案,除非你定製了你有循環QMovie的地方,以及你影響基礎寬度的標籤在你完成的百分比。將是一個有用的部件壽。 – 2012-08-12 21:49:24