QProgressBarの外観をスタイルシートでカスタマイズしたいと思います。そのアニメーション化された「不確定」な外観を与えたいと思います。そこで、の背景に貼り付けるアニメーションGIFを作成しましたQProgressBar::chunk
。
正常に表示されますが、画像は静止しており、アニメーションはありません。提案や回避策はありますか?
OSX10.8でPyQt4.9.4を実行しています。
QProgressBarの外観をスタイルシートでカスタマイズしたいと思います。そのアニメーション化された「不確定」な外観を与えたいと思います。そこで、の背景に貼り付けるアニメーションGIFを作成しましたQProgressBar::chunk
。
正常に表示されますが、画像は静止しており、アニメーションはありません。提案や回避策はありますか?
OSX10.8でPyQt4.9.4を実行しています。
したがって、これはあなたが直面しているもう少し複雑な問題です。
QProgressBarは、ループからの情報または決定された量に依存して、完了率を表します。コードを使用して値を設定すると、Qtはプログレスバーの値を設定して再描画し、更新された値を表示します。これには、実際にはループ内で数ミリ秒の処理が必要です。これを行わなかった場合、Qtの最適化は再描画されません。これは同期です。
プロセスが実際にクライアント側から移動し、サーバーで処理されて応答を待機しているため、目的の「不確定」な外観(AJAX gifスピナーやバーなど)が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
...