私はpyqt QProgressBarを複数のスレッドから更新しようとしています。これを行うための最善の方法は、シグナルをメインのGUIスレッドに戻すことです(QProgressBarオブジェクトワーカーのスレッドには、それが動作するように見えたが、私は通訳で大量の警告を得た)。次のコードでは、progressSignalシグナルを設定し、スレッドに接続して(今のところ)出力されたものだけを出力します。次に、各スレッドから合計パーセンテージを出します。私は、スレッド47の外にランダムな放射を放つだけで、これはスレッドの外で動作することを知っています。それを経由させるように見えることはありませんので、しかしライン36からEMITは、何をトリガしません...pyqt threading threadからのシグナルを放出
import Queue, threading
from PyQt4 import QtCore
import shutil
import profile
fileQueue = Queue.Queue()
class Communicate(QtCore.QObject):
progressSignal = QtCore.pyqtSignal(int)
class ThreadedCopy:
totalFiles = 0
copyCount = 0
lock = threading.Lock()
def __init__(self, inputList, progressBar="Undefined"):
self.totalFiles = len(inputList)
self.c = Communicate()
self.c.progressSignal.connect(self.updateProgressBar)
print str(self.totalFiles) + " files to copy."
self.threadWorkerCopy(inputList)
def CopyWorker(self):
while True:
self.c.progressSignal.emit(2000)
fileName = fileQueue.get()
shutil.copy(fileName[0], fileName[1])
fileQueue.task_done()
with self.lock:
self.copyCount += 1
percent = (self.copyCount * 100)/self.totalFiles
self.c.progressSignal.emit(percent)
def threadWorkerCopy(self, fileNameList):
for i in range(16):
t = threading.Thread(target=self.CopyWorker)
t.daemon = True
t.start()
for fileName in fileNameList:
fileQueue.put(fileName)
fileQueue.join()
self.c.progressSignal.emit(1000)
def updateProgressBar(self, percent):
print percent
UPDATE:
相続人は、GUIでサンプルを。この1つの実行されますが、それは定期的にクラッシュし、UIは、いくつかの奇妙なもの(プログレスバーが完了していない、など)を行い、非常に不安定である
Main.py:
import sys, os
import MultithreadedCopy_5
from PyQt4 import QtCore, QtGui
def grabFiles(path):
# gets all files (not folders) in a directory
for file in os.listdir(path):
if os.path.isfile(os.path.join(path, file)):
yield os.path.join(path, file)
class MainWin(QtGui.QWidget):
def __init__(self):
super(MainWin, self).__init__()
self.initUI()
def initUI(self):
self.progress = QtGui.QProgressBar()
box = QtGui.QVBoxLayout()
box.addWidget(self.progress)
goBtn = QtGui.QPushButton("Start copy")
box.addWidget(goBtn)
self.setLayout(box)
goBtn.clicked.connect(self.startCopy)
def startCopy(self):
files = grabFiles("folder/with/files")
fileList = []
for file in files:
fileList.append([file,"folder/to/copy/to"])
MultithreadedCopy_5.ThreadedCopy(fileList, self.progress)
def main():
app = QtGui.QApplication(sys.argv)
ex = MainWin()
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
MultithreadedCopy_5.py:
import Queue, threading
from PyQt4 import QtCore
import shutil
import profile
fileQueue = Queue.Queue()
class Communicate(QtCore.QObject):
progressSignal = QtCore.pyqtSignal(int)
class ThreadedCopy:
totalFiles = 0
copyCount = 0
lock = threading.Lock()
def __init__(self, inputList, progressBar="Undefined"):
self.progressBar = progressBar
self.totalFiles = len(inputList)
self.c = Communicate()
self.c.progressSignal.connect(self.updateProgressBar, QtCore.Qt.DirectConnection)
print str(self.totalFiles) + " files to copy."
self.threadWorkerCopy(inputList)
def CopyWorker(self):
while True:
fileName = fileQueue.get()
shutil.copy(fileName[0], fileName[1])
fileQueue.task_done()
with self.lock:
self.copyCount += 1
percent = (self.copyCount * 100)/self.totalFiles
self.c.progressSignal.emit(percent)
def threadWorkerCopy(self, fileNameList):
for i in range(16):
t = threading.Thread(target=self.CopyWorker)
t.daemon = True
t.start()
for fileName in fileNameList:
fileQueue.put(fileName)
fileQueue.join()
def updateProgressBar(self, percent):
self.progressBar.setValue(percent)
#profile.run('ThreadedCopy()')
私は、PythonのスレッドがバックメインPyQtはアプリに信号を発することができないことを実現するために始めているので、これを行うには「正しい」方法はPyQtはをQThreadsとなります - 私はしたくありません。ワーカースレッドが終了するたびにメインスレッドでシグナルを出力する簡単な方法がありますか? – Spencer
あなたの質問に表示されている例の問題を少なくとも修正する必要がある解決策については私の答えを見てください。 – ekhumoro