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...
- Your StuffWindow MainWindow should be created (not shown)
- Call a
login()
method that creates and exec_() your login QDialog as a application MODAL dialog - Start the app.exec_() event loop now, and wait for the user to interact with login
- 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 aQDialog
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?"