Skip to content Skip to sidebar Skip to footer

How To Communicate Or Switch Between Two Windows In Pyqt?

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.St

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:

classMainWindow():

    deflogin():
        loginDialog = LoginDialog()

        # this is modal. wait for it to closeif 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

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

    defcheck(self):
        ifstr(self.password.text()) == "12345": # do actual login check
            self.accept()
        else:
            pass# or inform the user about bad username/passwordclassMainWindow(QtGui.QMainWindow):
    def__init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

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

    defsetUsername(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()
    ifnot 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)

Solution 4:

This is PyQt5 updated version of Avaris. Some exception handling was added to show how to catch a few errors (while coding your thing. Enjoy!

#!/usr/bin/env python# -*- coding: utf-8 -*-# Ref to this OP question. https://stackoverflow.com/questions/9689053/how-to-communicate-or-switch-between-two-windows-in-pyqt4import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QDialog, QDialogButtonBox, QFormLayout, QLabel, QLineEdit, QWidget, QVBoxLayout

classLoginDialog(QtWidgets.QDialog):
    def__init__(self, parent=None):
        super(LoginDialog, self).__init__(parent)

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

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

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

    defcheck(self):
        ifstr(self.password.text()) == "12345": # do actual login check
            self.accept()
        else:
            pass# or inform the user about bad username/passworddefmy_exception_hook(exctype, value, traceback):
        # Print the error and tracebackprint(exctype, value, traceback)
        # Call the normal Exception hook after
        sys._excepthook(exctype, value, traceback)
        sys.exit(1)

    # Back up the reference to the exceptionhook
    sys._excepthook = sys.excepthook

    # Set the exception hook to our wrapping function
    sys.excepthook = my_exception_hook


classMainWindow(QtWidgets.QMainWindow):
    def__init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

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

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


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

    login = LoginDialog()
    ifnot login.exec_(): # 'reject': user pressed 'Cancel', so quit
        sys.exit(-1)      # instead of -1 another action can be triggered here.     # 'accept': continue
    main = MainWindow()

    # get the username, and supply it to main window
    main.setUsername(login.username.text())
    main.show()

    sys.exit(app.exec_())

Solution 5:

to match username and password.

import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QDialog, QDialogButtonBox, QFormLayout, QLabel, QLineEdit, QWidget, QVBoxLayout, QMessageBox

classLoginDialog(QtWidgets.QDialog):
    def__init__(self, parent=None):
        super(LoginDialog, self).__init__(parent)

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

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

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

    defcheck(self):
        ifstr(self.username.text()) == "foo"andstr(self.password.text()) == "bar": # do actual login check
            self.accept()
        else:
            QMessageBox.warning(
                self, 'Error', 'Bad user or password')
            pass# or inform the user about bad username/passworddefmy_exception_hook(exctype, value, traceback):
        # Print the error and tracebackprint(exctype, value, traceback)
        # Call the normal Exception hook after
        sys._excepthook(exctype, value, traceback)
        sys.exit(1)

    # Back up the reference to the exceptionhook
    sys._excepthook = sys.excepthook

    # Set the exception hook to our wrapping function
    sys.excepthook = my_exception_hook


classMainWindow(QtWidgets.QMainWindow):
    def__init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

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

    defsetUsername(self, username):
        # do whatever you want with the username
        self.username = username
        self.label.setText("%s%s%s" % ("Username entered: ", self.username, "\npassword ok!"))


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

    login = LoginDialog()
    ifnot login.exec_(): # 'reject': user pressed 'Cancel', so quit
        sys.exit(-1)      # instead of -1 another action can be triggered here.     # 'accept': continue
    main = MainWindow()

    # get the username, and supply it to main window
    main.setUsername(login.username.text())
    main.show()

    sys.exit(app.exec_())

Post a Comment for "How To Communicate Or Switch Between Two Windows In Pyqt?"