我一直在尝试找到一种同时运行和更新多个进度条的方法,但到目前为止我运气不佳。我想我还需要一个查询/运行/重置系统才能使其工作。
有任何想法吗?我一直在玩 QThreadPool 和 QRunnable,但没有成功。
** 更新:根据这篇很棒的文章更新了代码。它似乎有效,但存在许多问题:
我收到警告:QObject::startTimer: timers cannot be started from another thread
一旦我更改了 execute_this_fn 函数中的更新频率(比如更新 1、2、3 等),整个事情就会崩溃。
我希望能够将进度条的数量限制为 3。如果我单击开始按钮超过 3 次,它们应该被查询。
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_()