【发布时间】:2017-05-22 11:07:31
【问题描述】:
我正在尝试使用imap lib 制作邮箱检查器,它在没有 gui 的情况下与 python、队列和多线程一起工作得很好。
但是当我尝试放置一个 gui 时,我所做的每一个功能,都让 gui 冻结直到完成。
我从各种文档(添加 qthread、signal、cursor 等)和教程中尝试了很多东西,但对我没有用。
有人可以帮助我了解如何在运行函数时将文本设置或附加到 QtextEdit,因为它只有在完成后才能工作。
这是我的代码:
class Checker(QtCore.QThread):
signal = QtCore.pyqtSignal(object)
def __init__(self, lignesmailtocheck):
QtCore.QThread.__init__(self)
self.lignesmailtocheck = lignesmailtocheck
def run(self):
lignemailtocheck = self.lignesmailtocheck.strip()
maillo, passo = lignemailtocheck.split(":",1)
debmail, finmail = maillo.split("@",1)
setimap =["oultook.com:imap-mail.outlook.com", "gmail.com:imap.gmail.com"]
for lignesimaptocheck in sorted(setimap):
ligneimaptocheck = lignesimaptocheck.strip()
fai, imap = ligneimaptocheck.split(":",1)
if finmail == fai:
passo0 = passo.rstrip()
try :
mail = imaplib.IMAP4_SSL(imap)
mail.login(maillo, passo)
mailboxok = open("MailBoxOk.txt", "a+", encoding='utf-8', errors='ignore')
mailboxok.write(maillo+":"+passo+"\n")
mailboxok.close()
totaly = maillo+":"+passo0+":"+imap
print(maillo+":"+passo+"\n")
self.send_text.emit(totaly)
time.sleep(1)
except imaplib.IMAP4.error:
print ("LOGIN FAILED!!! ")
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(400, 300)
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(150, 210, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.gogogo)
self.openliste = QtWidgets.QToolButton(Form)
self.openliste.setGeometry(QtCore.QRect(40, 110, 71, 21))
self.openliste.setObjectName("openliste")
self.textEdit = QtWidgets.QTextEdit(Form)
self.textEdit.setGeometry(QtCore.QRect(170, 50, 201, 121))
self.textEdit.setObjectName("textEdit")
self.progressBar = QtWidgets.QProgressBar(Form)
self.progressBar.setGeometry(QtCore.QRect(10, 260, 381, 23))
self.progressBar.setValue(0)
self.progressBar.setObjectName("progressBar")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.pushButton.setText(_translate("Form", "PushButton"))
self.openliste.setText(_translate("Form", "..."))
def gogogo(self):
mailtocheck = open('File/toCheck.txt', 'r', encoding='utf-8', errors='ignore').readlines()
setmailtocheck = set(mailtocheck)
for lignesmailtocheck in sorted(setmailtocheck):
checker = Checker(lignesmailtocheck)
thread = QThread()
checker.moveToThread(thread)
# connections after move so cross-thread:
thread.started.connect(checker.run)
checker.signal.connect(self.checkedok)
thread.start()
def checkedok(self, data):
print(data)
self.textEdit.append(data)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
【问题讨论】:
-
您必须描述重现问题的步骤。当我运行它(删除几行导入后)并单击按钮时,我看到 YY 打印到控制台但没有冻结。请发布导致问题的代码,并附上冻结的步骤,我们可以帮助您解决这个问题。
-
抱歉导入,我尝试了很多不同的方法使其工作......步骤是:点击按钮后,程序在文件'File/toCheck. txt' 格式为 email:pass 并且登录信息被发送到 qtreah。在线程中使用 imap 尝试登录,如果登录正常,QtextEdit 打印有效登录。如果您尝试使用 2-3 个电子邮件:传入文件,您没有时间看到它无法正常工作,但如果您尝试大量使用 gui 冻结和 QtextEdit 仅在完成时打印
-
您在该循环中创建了多少线程? Python GIL 阻止线程并发执行,并且有可能拥有大量线程只是将花费在主线程(重绘 GUI)上的时间减少到看起来像是被冻结而不是更新的程度。跨度>
-
在此代码中,我在文件 .txt 中逐行发送 1 个线程。但无论如何,它可以有 2、10、100 或 1000 个 gui 冻结。我首先尝试对 python 线程和队列做同样的事情,但我发出与 Qthread 相同的问题。即使发出信号,gui 也会冻结,并且 gui 仅在完成时更新。请告诉我我做错了什么。
-
我建议从 QObject 派生 Checker 线程并创建一个 QThread 对象和 checker.moveTo(thread)。
标签: python pyqt pyqt5 python-multithreading