所以我有一个GUI,它使用大量的方法来登录程序并检索信息。所以我开始将该代码集成到Qthread中;一切都工作正常,直到我记得测试错误消息,似乎Qthread内的发出信号有时不会被我的主代码捕获。
以下是我正在讨论的代码:
(python 3,pyqt5)
代码修订版1 - 更改日志: testf - 所有值现在都使用信号和插槽加载到Qthread中 - 未经测试,将很快更新 - Qthread - 添加"信号接收功能" (tt信号添加到loginb)
std::tuple
线程代码:
def testf(self):
self.movie.start()
self.gif.show()
self.myThread = thread()
self.loginb.tt.connect(self.myThread.valueset)
self.loginb.tt.emit(self.userfield.text(), self.pwfield.text(), self.checkBox.text(), self.checkBox.isChecked())
self.myThread.start()
self.myThread.done.connect(self.threadrelay)
def threadrelay(self, code, text): #decides what to do given the thread's emited signal arguments
print('enter relay',code)
self.movie.stop()
self.gif.hide()
self.myThread.exit()
if code == 3:
print(text)
print('trying to open main diag')
self.Omaindialog(text)
elif code == 4:
self.wrongpass.setText(text)
self.wrongpass.show()
else:
self.errordiag(text,code)
这只显示受影响的部分(可能更多我的代码受此影响,idk但我真的不知道这里发生了什么) - 所以" testf"函数被调用(按钮),它启动qthread,然后qthread发出带有参数的完成信号,这些参数将由" threadrelay"功能
这是一些输出(每个按钮点击之间约5-10秒):
class thread(QtCore.QThread):
done=pyqtSignal(int, str)
def valueset(self,u,p,c,ci):
print('received values')
self.user=u
self.paw=p
self.check=c
self.checkis=ci
def run (self):
print(self.check == "Save password", self.check)
if (self.paw=='' or self.user=='') and self.check == "Save password":
print('if 1')
txt=("loads of html code here")
self.done.emit(4,txt)
print('emited')
elif ('@' not in self.user or '.' not in self.user) and self.check == "Save password":
print('if 2')
txt=("loads of html code here")
self.done.emit(4,txt)
print('emited')
else:
EDIT1:大声笑我出去喝了一杯咖啡回来了,现在它的工作频率比没有...我感到困惑......它仍然无法正常工作有时虽然
EDIT2:我意识到我可以在 Qthread之前检查,但是这个问题可能也会发生在Qthread中的其余 emits (我刚刚和#39; t抓住它了,我想避开它并知道错误...
关于运行中的代码:复选框是多用途的,用于保存和加载密码(其中的文本会相应更改:如果有可用的密码,则自动勾选使用保存;如果用户取消,则为更改为"保存密码"选项); @或。不在usr.txt()中是因为用户必须是电子邮件。 wp(wrongpass)是一个标签,显示'请填写两个字段'或者'插入有效的电子邮件'。
更新:使用信号/插槽传递变量并没有解决我的问题。但是我修复了它,我发现可能Qthread正在快速发出信号,所以我在发出信号之前在if和elif中加了一个time.sleep(1),它完美无缺! - 这真的是原因吗?
答案 0 :(得分:0)
我认为问题出在self.check.text () ==" Save password "
注意:
self.checkBox = QtWidgets.QCheckBox('Save password', self)
self.checkBox.toggle()
self.checkBox.stateChanged.connect(self.changeTitle)
self.stateCheckBox = 2
def changeTitle(self, state):
self.stateCheckBox = state
试试我:
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtCore import pyqtSignal, Qt
class Thread1(QtCore.QThread):
done = pyqtSignal(int, str)
def __init__(self, usr, paw, wp, check, parent=None):
QtCore.QThread.__init__(self)
self.user = usr
self.paw = paw
self.wp = wp
self.check = check
def run (self):
if (self.paw=='' or self.user=='' or self.wp=='') :
txt=("Error: enter user or password or wrongpass")
self.done.emit(4, txt)
elif (self.paw != self.wp):
txt=("Error: password ")
self.done.emit(4, txt)
elif self.check:
txt=("Save data")
self.done.emit(4, txt)
#elif ('@' not in self.user.text() or '.' not in self.user.text()) and self.check.text() == "Save password":
# I do not know what it is
elif ('@' not in self.user or '.' not in self.user) and self.check:
print('\nif 2')
txt=("loads of html code here")
self.done.emit(4, txt)
print('emited')
else:
txt=("do not save data")
self.done.emit(4, txt)
class App(QtWidgets.QWidget):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.userfield = QtWidgets.QLineEdit(self)
self.userfield.setPlaceholderText("userfield")
self.pwfield = QtWidgets.QLineEdit(self)
self.pwfield.setPlaceholderText("pwfield")
self.wrongpass = QtWidgets.QLineEdit(self)
self.wrongpass.setPlaceholderText("wrongpass")
self.checkBox = QtWidgets.QCheckBox('Save password', self)
self.checkBox.toggle()
self.checkBox.stateChanged.connect(self.changeTitle)
self.stateCheckBox = 2
self.but1 = QtWidgets.QPushButton("testf", self)
self.but1.clicked.connect(self.testf)
self.label = QtWidgets.QLabel("", self)
self.grid1 = QtWidgets.QGridLayout()
self.grid1.addWidget(self.userfield, 0, 0, 1, 20)
self.grid1.addWidget(self.pwfield, 1, 0, 1, 20)
self.grid1.addWidget(self.wrongpass, 2, 0, 1, 20)
self.grid1.addWidget(self.checkBox, 3, 0, 1, 20)
self.grid1.addWidget(self.but1, 4, 0, 1, 20)
self.grid1.addWidget(self.label, 6, 0, 1, 20)
self.grid1.setContentsMargins(10, 10, 10, 10)
self.setLayout(self.grid1)
def testf(self): # starter function - called by pushbutton
#self.myThread = thread(self.userfield,self.pwfield, self.wrongpass, self.checkBox)
#self.myThread = Thread1(self.userfield, self.pwfield, self.wrongpass, self.stateCheckBox)
self.myThread = Thread1(str(self.userfield.text()),
str(self.pwfield.text()),
str(self.wrongpass.text()),
int(self.stateCheckBox))
self.myThread.start()
self.myThread.done.connect(self.threadrelay)
def threadrelay(self, code, text): #decides what to do given the thread's emited signal arguments
# I do not know what it is
#self.movie.stop()
#self.gif.hide()
self.myThread.exit()
if code == 3:
print(text)
print('trying to open main diag')
self.Omaindialog(text) # I do not know what it is
elif code == 4:
self.label.setText(text)
else:
self.errordiag(text, code)
def changeTitle(self, state):
self.stateCheckBox = state
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
myapp = App()
myapp.show()
sys.exit(app.exec_())