How to communicate or switch between two windows in PyQt?

牧云@^-^@ 提交于 2019-12-18 04:25:12

问题


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


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



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



回答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)



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



回答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

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.username.text()) == "foo" and str(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/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("%s%s%s" % ("Username entered: ", self.username, "\npassword ok!"))


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


来源:https://stackoverflow.com/questions/9689053/how-to-communicate-or-switch-between-two-windows-in-pyqt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!