Итак, это немного более сложная проблема, с которой вы столкнулись.
QProgressBar полагается на информацию из цикла или некоторую определенную сумму для представления процента выполнения. Когда вы устанавливаете значение через свой код, Qt устанавливает значение индикатора выполнения, перерисовывает его и, таким образом, показывает обновленное значение. На самом деле это занимает несколько миллисекунд обработки в вашем цикле. Если бы вы этого не сделали, оптимизация Qt никогда бы не перерисовывалась. Это синхронно.
«Неопределенный» вид, к которому вы стремитесь (например, счетчик GIF AJAX или полоса), используется в Интернете, потому что процесс фактически переместился со стороны клиента и обрабатывается на сервере и ожидает ответа. Процесс клиента вообще не блокируется, так что можно бесплатно обновить интерфейс роликом.
Вы можете добиться желаемого вида, используя QMovie в QLabel:
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
...
У меня есть виджет-загрузчик, который я использую всякий раз, когда делаю что-то подобное в своей библиотеке графического интерфейса. Если вы хотите увидеть код для него/использовать его, он находится по адресу 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
...
person
Eric Hulser
schedule
10.08.2012