0

I have a large app in PyQt5 that includes a login/logout element.

Main element:

class BigProgram(QMainWindow, QWidget):
    def __init__(self):
        super(BigProgram, self).__init__()
        self.show()
        # additional background tasks ...
        progress = QProgressDialog(self)  
        # elements that move the progress...
        self.login = Login(self)
        self.login.exec() # This opens a dialog and collects the credentials
        # etc.


if __name__.endswith('__main__'):
    app = QCoreApplication.instance()
    if app is None:
        app = QApplication(sys.argv)
    else:
        app.close()
    execute = BigProgram()
    sys.exit(app.exec_())

The Login element:

class Login(QDialog):   
    signal = pyqtSignal(str, str, bool)   
    # Signal sent to another class, Login_Controller, which holds the control elements

    def __init__(self, parent):
        super(Login, self).__init__(parent)
        self.root = parent
        self.logic = Login_Controller(view=Login)

        self.formGroupBox = QGroupBox('Login')
        form_layout = QFormLayout()
        
        self.username = QLineEdit()     
        self.username.setMinimumSize(600, 25)
        form_layout.addRow(QLabel('E-mail:'), self.username)

        self.password = QLineEdit()     
        self.password.setEchoMode(QLineEdit.Password)      
        form_layout.addRow(QLabel('Password:'), self.password)

        self.formGroupBox.setLayout(form_layout)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        buttonBox.accepted.connect(self._send_login)
        buttonBox.rejected.connect(self.reject)
        
        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.formGroupBox)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)
       
        self.setWindowTitle('User Login')
        self.setWindowModality(Qt.ApplicationModal)


    def _send_login(self):
        self.signal.connect(self.logic.login)

        self.signal.emit(self.username.text(), self.password.text())

        # This closes the login_dialog box
        self.password.clear()
        self.close()

It works, the first time. Upon starting the program, the Login opens, inputs pass to Login_Controller and successfully authenticate the user, and a success message appears. When the user closes the success message, the login dialog also closes.
The problem is when a user logs out (call to Login_Controller to revoke tokens; it works) and logs in for a second time. User enters credentials, hits OK, authentication occurs, success message shows. Hit OK. Login dialog does not close, authentication occurs for a 2nd time, the success message shows. Hit OK. Now everything closes and seems okay. If the user logs out and logs in for the 3rd time, this repeats except with 3 authentications, not 2.

Pressing the login button triggers self.login.re_auth() which is simply

def re_auth(self):
   self.show()

I'm not re-instantiating the Login class, but each time I use the re_auth() I seem to be creating an additional dialog.

Why is the self.close() not actually terminating this dialog? Is there a better way to do this?

Much thanks to any help!

A_Wunder
  • 96
  • 1
  • 7
  • You didn't provide enough code (where is `Login_Controller` and what does it do?), but one thing is certain: doing `self.signal.connect` every time `_send_login` is called is *wrong*. The result would be that you'll be calling `self.logic.login` *every single time* `self.signal` is emitted, exponentially. You call it once? You connect it once. You call it again? You're calling it twice *after that*. Which will cause the call four more times. And then 8, 16, etc. Move that in the `__init__`. – musicamante Jan 27 '22 at 23:07
  • Brilliant! THANK YOU @musicamante! I moved the connect to the bottom of the `__init__` and it now works perfectly. – A_Wunder Jan 28 '22 at 14:29

0 Answers0