【发布时间】:2017-05-15 02:21:23
【问题描述】:
我正在尝试在 PyQT GUI 中实现线程,但遇到了麻烦。一些背景,我有一个独立的脚本卸载了一些软件,删除了一些文件夹,然后重新安装了一个更新的版本。我使用线程模块删除文件夹,为每个文件夹启动一个新线程。有几个文件夹很大并且需要一些时间,所以我会遍历单独的线程,但会跳过较大的文件夹并加入线程:
thread = threading.Thread(name=portalDirToDelete,target=deleteFolder,args=(portalDirToDelete,))
thread.start()
....
for thread in threading.enumerate():
if not "MainThread" in thread.getName() and not "content" in thread.getName() and not "temp" in thread.getName():
thread.join()
一旦我开始使用 PyQT4 制作 UI,我发现线程在我尝试加入它们之前不会启动。我做了一些阅读并了解到使用线程模块不再起作用,(How to keep track of thread progress in Python without freezing the PyQt GUI?)所以我开始研究 QThreads,但运气不佳。以下是我的其他脚本正在执行的简化版本:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'Samples\ThreadUI1.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
import shutil, os, time
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class workerThread(QtCore.QObject):
finished = QtCore.pyqtSignal()
def deleteFolder(self,path):
if os.path.exists(path):
shutil.rmtree(path)
self.finished.emit()
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(115, 66)
self.runApp = QtGui.QPushButton(Form)
self.runApp.setGeometry(QtCore.QRect(20, 20, 75, 23))
self.runApp.setObjectName(_fromUtf8("runApp1"))
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
self.runApp.clicked.connect(lambda:self.runSetups())
def retranslateUi(self, Form):
Form.setWindowTitle(_translate("Form", "Form", None))
self.runApp.setText(_translate("Form", "Run App", None))
def usingMoveToThread(self,path):
self.app = QtCore.QCoreApplication([])
self.objThread = QtCore.QThread()
self.obj = workerThread()
self.obj.moveToThread(self.objThread)
self.obj.finished.connect(self.objThread.quit)
self.objThread.started.connect(self.obj.deleteFolder(path))
self.objThread.finished.connect(app.exit)
self.objThread.start()
def runSetups(self):
self.usingMoveToThread(r"C:\arcgisportal")
for x in range(1,11):
print(x)
time.sleep(1)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Form = QtGui.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
我的想法可能是错误的,但我的方法是在新线程中启动删除文件夹的过程,然后查看它是否继续循环打印。我一直使用Threading and PyQT 作为主要指南。关于子类化 QThread 似乎有不同的意见,所以我只是去了这个博客,(https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/)不这样做。
我使用的是 Python 2.7、PyQt4 4.11.4,这个应用是通过 UI Designer 制作的。我知道更新生成的 ui/py 文件不是一个好主意,我在其他地方没有这样做,只是将此示例作为上下文提供。
感谢任何帮助!
更新
如果我打开一个模态 QMessageBox() 并添加一个关闭 QMessageBox 的按钮,当它打开时,较大文件夹中的文件夹将被删除。一旦我关闭 QMessageBox(),文件夹就不再被删除,所以我对线程和 UI 有一些不清楚的地方。
【问题讨论】:
标签: python multithreading pyqt