gpt4 book ai didi

python - 在不同线程中运行进度条 - Pyside

转载 作者:行者123 更新时间:2023-12-01 03:57:35 25 4
gpt4 key购买 nike

我想在与代码其余部分不同的线程中运行进度条,但我想控制进度条如何从主线程更新。

这是可能的吗?

这是我到目前为止所拥有的:

import time
from PySide import QtGui
from PySide import QtCore
from PySide import QtUiTools

class progressBar(QtGui.QDialog, QtCore.QThread):

def __init__(self, window, title=None):
super(progressBar, self).__init__(window)
QtCore.QThread.__init__(self)

self.title = title or 'Progress'
self.setupUi()
self.show()

def setupUi(self):
self.setObjectName("Thinking")
self.gridLayout = QtGui.QGridLayout(self)
self.gridLayout.setObjectName("gridLayout")
self.progressBar = QtGui.QProgressBar(self)
self.gridLayout.addWidget(self.progressBar, 0, 0, 1, 1)

# ADJUSTMENTS
self.setMaximumSize(280, 50)
self.setMinimumSize(280, 50)
self.setWindowTitle(self.title)


def increase(self, inc):
self.progressBar.setProperty("value", inc)
time.sleep(0.01)

def run(self):
for i in range(1,101):
self.increase(i)



progressThread = progressBar(QtGui.QApplication.activeWindow())
progressThread.start()

这似乎在线程内正确运行进度条,但它完全由 run 函数控制。

我尝试删除 run 函数并将此代码添加到我的主线程中:

progressThread = progressBar(QtGui.QApplication.activeWindow())
progressThread.start()

for i in range(1,101):
progressThread.increase(i)

但这似乎不起作用。

对此的任何帮助都会很棒......谢谢

最佳答案

我相信bnaecker , Brendan AbelSteve Cohen已经在他们的评论中为您提供了关键信息。正如他们已经说过的,只要 UI 在主线程上运行,您绝对可以在单独的线程中运行进度条和逻辑。

这是一个应该按照您想要的方式工作的示例:

import time, random
import threading

from PySide import QtCore, QtGui


class ProgressWidget(QtGui.QWidget):

# just for the purpose of this example,
# define a fixed number of threads to run
nthreads = 6

def __init__(self):
super(ProgressWidget, self).__init__()
self.threads = []
self.workers = []
self.works = [0 for i in range(self.nthreads)]
self.setupUi()
self.setupWorkers()
self.runThreads()

def drawProgessBar(self):
self.progressBar = QtGui.QProgressBar(self)
self.progressBar.setGeometry(QtCore.QRect(20, 20, 582, 24))
self.progressBar.minimum = 1
self.progressBar.maximum = 100
self.progressBar.setValue(0)

def setupUi(self):
self.setWindowTitle("Threaded Progress")
self.resize(600, 60)
self.drawProgessBar()

def buildWorker(self, index):
"""a generic function to build multiple workers;
workers will run on separate threads and emit signals
to the ProgressWidget, which lives in the main thread
"""
thread = QtCore.QThread()
worker = Worker(index)
worker.updateProgress.connect(self.handleProgress)
worker.moveToThread(thread)
thread.started.connect(worker.work)
worker.finished.connect(thread.quit)
QtCore.QMetaObject.connectSlotsByName(self)
# retain a reference in the main thread
self.threads.append(thread)
self.workers.append(worker)

def setupWorkers(self):
for i in range(self.nthreads):
self.buildWorker(i)

def runThreads(self):
for thread in self.threads:
thread.start()

def handleProgress(self, signal):
"""you can add any logic you want here,
it will be executed in the main thread
"""
index, progress = signal
self.works[index] = progress
value = 0
for work in self.works:
value += work
value /= float(self.nthreads)
# management of special cases
if value >= 100:
self.progressBar.hide()
return
# else
self.progressBar.setValue(value)
print 'progress (ui) thread: %s (value: %d)' % (threading.current_thread().name, value)


class Worker(QtCore.QObject):
"""the worker for a threaded process;
(this is created in the main thread and
then moved to a QThread, before starting it)
"""

updateProgress = QtCore.Signal(tuple)
finished = QtCore.Signal(int)

def __init__(self, index):
super(Worker, self).__init__()
# store the Worker index (for thread tracking
# and to compute the overall progress)
self.id = index

def work(self):
for i in range(100):
print 'worker thread: %s' % (threading.current_thread().name, )
# simulate some processing time
time.sleep(random.random() * .2)
# emit progress signal
self.updateProgress.emit((self.id, i + 1))
# emit finish signal
self.finished.emit(1)


if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
ui = ProgressWidget()
ui.show()
sys.exit(app.exec_())

这是一个最小的分割:

  • QThread 存在于创建它们的主线程中(而不是它们管理的线程中)
  • 为了在单独的线程上运行任务,必须使用moveToThread将它们传递给QThreads。方法(工作人员需要子类化 QObject 才能使用该方法)
  • 工作人员发送信号来更新进度条并通知他们已完成任务
  • 在此示例中,我们正在运行多个任务,每个任务都在其自己的线程中。进度信号被发送回主线程,更新进度条的逻辑在主线程中运行

旁注:在控制台中,工作人员的输出指的是“虚拟”线程。这似乎与threading有关。模块不了解 QThreads(至少这是我从 here 得到的)。尽管如此,这似乎足以证明工作人员的任务是在单独的线程上运行的。如果有人有更准确的信息,请随意扩展。

对于那些想了解有关此主题的更多信息的人,here is a link很多文章都提到过。

关于python - 在不同线程中运行进度条 - Pyside,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37174826/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com