How to communicate or switch between two windows in PyQt?

10,078

Solution 1

Regardless of your description, I think your LoginWindow should be a QDialog, and your StuffWIndow be the MainWindow, and function like this...

  1. Your StuffWindow MainWindow should be created (not shown)
  2. Call a login() method that creates and exec_() your login QDialog as a application MODAL dialog
  3. Start the app.exec_() event loop now, and wait for the user to interact with login
  4. User interacts with login dialog, and the result of the dialog closing will then allow your app to check its values and choose to show its main interface.

Here is a quick outline:

class MainWindow():

    def login():
        loginDialog = LoginDialog()

        # this is modal. wait for it to close
        if loginDialog.exec_():
            # dialog was accepted. check its values and maybe:
            self.show()

        else:
            # maybe reshow the login dialog if they rejected it?
            loginDialog.exec_()


if __name__ == "__main__":

    app = QApp
    win = MainWindow()
    win.login()
    app.exec_()

Solution 2

I do agree most of the points jdi raised, but I prefer a slightly different approach.

  • LoginWindow should be a QDialog started as MODAL.
  • Check the return of exec_() (i.e. accept/reject) for login or cancel/quit.
  • Check the login inside the LoginWindow
  • If successful login, launch MainWindow with parameters supplied

I started coding a simple example before seeing jdi's answer. I might as well put it here.

import sys
from PyQt4 import QtGui, QtCore

class LoginDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        super(LoginDialog, self).__init__(parent)

        self.username = QtGui.QLineEdit()
        self.password = QtGui.QLineEdit()
        loginLayout = QtGui.QFormLayout()
        loginLayout.addRow("Username", self.username)
        loginLayout.addRow("Password", self.password)

        self.buttons = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
        self.buttons.accepted.connect(self.check)
        self.buttons.rejected.connect(self.reject)

        layout = QtGui.QVBoxLayout()
        layout.addLayout(loginLayout)
        layout.addWidget(self.buttons)
        self.setLayout(layout)

    def check(self):
        if str(self.password.text()) == "12345": # do actual login check
            self.accept()
        else:
            pass # or inform the user about bad username/password


class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.label = QtGui.QLabel()
        self.setCentralWidget(self.label)

    def setUsername(self, username):
        # do whatever you want with the username
        self.username = username
        self.label.setText("Username entered: %s" % self.username)


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)

    login = LoginDialog()
    if not login.exec_(): # 'reject': user pressed 'Cancel', so quit
        sys.exit(-1)      

    # 'accept': continue
    main = MainWindow()
    main.setUsername(login.username.text()) # get the username, and supply it to main window
    main.show()

    sys.exit(app.exec_())

Solution 3

Although this is not directly relevant to your question, you should always set QLineEdit.EchoMode for the password field as follows (see here):

self.password.setEchoMode(QtGui.QLineEdit.Password)
Share:
10,078
Cholavendhan
Author by

Cholavendhan

Doing ME Computer and Communication in Tamilnadu college of engineering in coimbatore.. Did BE CSE in K.S.Rangasamy College Of Technology-Erode,Tamilnadu,India

Updated on June 04, 2022

Comments

  • Cholavendhan
    Cholavendhan almost 2 years

    I am developing an application using python and Qt.

    I have designed 2 Main windows ie..QMainWindow (Not QWidget or QDialog) using Qt.

    Let it be.

    1.LoginWindow -- LoginUI(Qt)

    2.StuffWindow --- StuffUI

    1. First i should display Login Window.

    2. Then i should pass the username to StaffWindow (username needed for managing stuffs)

    3. StaffWindow should be shown and LoginWindow Should be Closed..

    How can i achieve this..? Help me..