J'ai essayé de trouver un moyen d'exécuter et de mettre à jour plusieurs barres de progression en même temps, mais jusqu'à présent, je n'ai pas de chance. Je suppose que j'ai aussi besoin d'un système que/run/reset pour que cela fonctionne.PySide - mise à jour de plusieurs barres de progression
Des idées? J'ai joué avec QThreadPool et QRunnable, mais sans succès.
** Mise à jour: Code mis à jour basé sur this grand article. Il semble fonctionner, mais il y a un certain nombre de problèmes:
Je reçois un avertissement: QObject :: startTimer: minuteries ne peuvent pas être démarré à partir d'un autre thread
Dès que je change la fréquence de mise à jour dans la fonction execute_this_fn (comme la mise à jour sur 1,2,3 etc), tout se bloque. Je veux être en mesure de limiter le nombre de barres de progression à 3. Si je clique sur le bouton de démarrage plus de trois fois, elles doivent être suspendues.
from PySide.QtGui import *
from PySide.QtCore import *
import time
import traceback, sys
class WorkerSignals(QObject):
finished = Signal()
error = Signal(tuple)
result = Signal(object)
progress = Signal(int)
class Worker(QRunnable):
def __init__(self, fn, bar, *args, **kwargs):
super(Worker, self).__init__()
self.fn = fn
self.bar = bar
self.args = args
self.kwargs = kwargs
self.signals = WorkerSignals()
# Add the callback to our kwargs
kwargs['progress_callback'] = self.signals.progress
@Slot()
def run(self):
# Retrieve args/kwargs here; and fire processing using them
try:
result = self.fn(self.bar, *self.args, **self.kwargs)
except:
traceback.print_exc()
exctype, value = sys.exc_info()[:2]
self.signals.error.emit((exctype, value, traceback.format_exc()))
else:
self.signals.result.emit(result) # Return the result of the processing
finally:
self.signals.finished.emit() # Done
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.counter = 0
self.layout = QVBoxLayout()
b = QPushButton("Start thread")
b.pressed.connect(self.start_me)
self.layout.addWidget(b)
w = QWidget()
w.setLayout(self.layout)
self.setCentralWidget(w)
self.show()
self.threadpool = QThreadPool()
print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
def progress_fn(self, n):
print("%d%% done" % n)
def execute_this_fn(self, bar, progress_callback):
for n in range(0, 5):
time.sleep(1)
calc = n*100/4
progress_callback.emit(calc)
bar.setValue(calc)
return "Done."
def print_output(self, s):
print(s)
def thread_complete(self):
print("THREAD COMPLETE!")
def start_me(self):
# Pass the function to execute
xx = self.progress_bar = QProgressBar()
self.layout.addWidget(xx)
worker = Worker(self.execute_this_fn, xx) # Any other args, kwargs are passed to the run function
worker.signals.result.connect(self.print_output)
worker.signals.finished.connect(self.thread_complete)
worker.signals.progress.connect(self.progress_fn)
# Execute
self.threadpool.start(worker)
app = QApplication([])
window = MainWindow()
app.exec_()
Qu'avez-vous essayé pour résoudre votre problème? Quel est le problème avec le code que vous affichez? – eyllanesc
Vous utilisez le modèle de travail incorrect. Vous ne déplacez pas le Worker sur le thread avant de l'exécuter. Cela entraîne probablement la mise en file d'attente de la connexion signal/emplacement. – deets
Ce code est juste un exemple pour une seule barre de progression. Je cherche un moyen d'avoir 5 barres de progression fonctionnant en même temps (avec des valeurs différentes). –