Pyqt - Сигнал, испускаемый на Qthread, иногда не принимается - PullRequest
0 голосов
/ 26 апреля 2018

, поэтому у меня есть графический интерфейс, который использует много возможностей для входа в программу и получения информации.Поэтому я начал интегрировать этот код в Qthread;все работало нормально, пока я не вспомнил, чтобы проверить сообщения об ошибках, кажется, что испускаемый сигнал внутри Qthread иногда не улавливается моим основным кодом.

Вот фрагмент кода, о котором я говорю:

(python 3, pyqt5)

Редакция кода 1 - журнал изменений: testf - все значения теперь загружаются в Qthread с использованием сигналов и слотов - непроверено, будетскоро обновление - Qthread - добавлена ​​«функция приема сигнала» (добавлен сигнал tt в loginb)

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)

код потока:

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:

это показываетзатрагивается только часть (может быть, это влияет на мой код, еще не знаю, я действительно не понимаю, что здесь происходит) - так вызывается функция «testf» (кнопка), она запускает qthread, затем qthread испускаетСигнал done с параметрами, которые будут оцениваться функцией "threadrelay".

Вот некоторые выходные данные (около 5-10 секунд между каждым нажатием кнопки):

True Save password
if 2
emited
True Save password
if 2
emited
True Save password
if 2
emited
True Save password
if 2
emited
True enter relaySave password <- only time it entered the "threadrelay" function)
4if 2

emited
True Save password
if 2
emited
True Save password
if 2
emited
True Save password
if 2
emited
True Save password
if 2
emited

EDIT1: lolя вышел за чашкой кофе, вернулся, и теперь он работает чаще, чем не ... Я сбит с толку ... иногда он все еще не работает, хотя

EDIT2: я понимаюя могу сделать эту проверку до Qthread, но эта проблема, вероятно, также произойдет с остальными испусками в Qthread (я просто не поймал его), и я 'Хотелось бы избежать этого и знать, что не так ...


О коде в действии: флажок универсален для сохранения и загрузки пароля (текст в нем изменяется соответственно: если естьявляется доступным паролем, автоматически помечается как сохраненный;если пользователь убрал галочку, он меняется на «сохранить пароль»);@ Или.Нет в usr.txt (), потому что пользователь должен быть по электронной почте.Wp (неправильный пароль) - это метка, которая отображает «пожалуйста, заполните оба поля» или «вставьте действительный адрес электронной почты».

Обновление : использование сигналов / слотов для передачи переменных не исправиломоя проблема.Но я исправил это, мне пришло в голову, что, может быть, Qthread испускает сигналы быстро, поэтому я добавил time.sleep (1) в if и elif, прежде чем испустить сигнал, и это работает отлично!- Это могло быть причиной?

1 Ответ

0 голосов
/ 26 апреля 2018

Я думаю, что проблема в 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

Попробуйте iy:

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_())               

enter image description here

...