¿Cómo comunicarse o cambiar entre dos ventanas en PyQt?

Estoy desarrollando una aplicación usando python y Qt.

He diseñado 2 ventanas principales, es decir … QMainWindow (no QWidget o QDialog) usando Qt.

Déjalo ser.

1.LoginWindow – LoginUI (Qt)

2. StuffWindow — StuffUI

  1. Primero debo mostrar la ventana de inicio de sesión.

  2. Entonces debo pasar el nombre de usuario a StaffWindow (nombre de usuario necesario para administrar cosas)

  3. Debería aparecer StaffWindow y se debería cerrar LoginWindow ..

Cómo puedo conseguir esto..? Ayuadame..

Independientemente de su descripción, creo que su LoginWindow debería ser un QDialog, y su StuffWindow ser la MainWindow, y funcionar así …

  1. Se debe crear su ventana principal de StuffWindow (no se muestra)
  2. Llame a un método de login() que crea y ejec_ () su inicio de sesión QDialog como un cuadro de diálogo MODAL de aplicación
  3. Inicie el bucle de eventos app.exec_ () ahora y espere a que el usuario interactúe con el inicio de sesión
  4. El usuario interactúa con el cuadro de diálogo de inicio de sesión, y el resultado del cierre del cuadro de diálogo permitirá a su aplicación verificar sus valores y elegir mostrar su interfaz principal.

Aquí hay un resumen rápido:

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

Estoy de acuerdo con la mayoría de los puntos que jdi planteó, pero prefiero un enfoque ligeramente diferente.

  • LoginWindow debe ser un QDialog iniciado como MODAL.
  • Verifique la devolución de exec_() (es decir, accept/reject ) para iniciar sesión o cancelar / salir.
  • Compruebe el inicio de sesión dentro de la LoginWindow inicio de LoginWindow
  • Si el inicio de sesión es exitoso, inicie MainWindow con los parámetros provistos

Comencé a codificar un ejemplo simple antes de ver la respuesta de jdi. Bien podría ponerlo aquí.

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

Aunque esto no es directamente relevante para su pregunta, siempre debe configurar QLineEdit.EchoMode para el campo de contraseña de la siguiente manera (ver aquí ):

 self.password.setEchoMode(QtGui.QLineEdit.Password) 

Esta es la versión actualizada de Avaris en PyQt5. Se agregó algo de manejo de excepciones para mostrar cómo detectar algunos errores (mientras codificas lo tuyo. ¡Disfruta!

 #!/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-pyqt4 import sys from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5.QtWidgets import QApplication, QDialog, QDialogButtonBox, QFormLayout, QLabel, QLineEdit, QWidget, QVBoxLayout class LoginDialog(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) 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 def my_exception_hook(exctype, value, traceback): # Print the error and traceback print(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 class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.label = 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 = QApplication(sys.argv) login = LoginDialog() if not 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_())