3

I have created a login window where the window will remain until the user enters the right password, and if the user presses the "X" button on the top right corner, the window should disappear. However, the window disappears even if the user enters the incorrect password.

Code:

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

        self.grid = QGridLayout(self)
        self.setGeometry(650, 350, 400, 150)
        self.setFixedSize(400, 150)

        self.UserLabels = QLabel(self)
        self.UserLabels.setText('Login Number:')
        self.grid.addWidget(self.UserLabels, 0, 0, 1, 1)

        self.textName = QLineEdit(self)
        self.grid.addWidget(self.textName, 0, 1, 1, 2)

        self.buttonLogin = QPushButton('Submit', self)
        self.buttonLogin.clicked.connect(self.closeGUI)
        self.grid.addWidget(self.buttonLogin, 2, 0, 1, 3)

        finish = QAction("Quit", self)
        finish.triggered.connect(self.closeWin)

    def closeGUI(self):
        self.close()
        return str(self.textName.text())

    def closeWin(self):
        self.close()
        return 1

def handleLogin():
    flag = 0
    while flag == 0:
        edit_params__QD = Login()
        edit_params__QD.exec_()
        if edit_params__QD.result() == 0:
            password = edit_params__QD.closeGUI()
            if password == '6':
                flag = 1
            else:
                flag = 0
        if edit_params__QD.closeWin() == 1:
            flag = 1

if __name__ == '__main__':
    app = QApplication(sys.argv)
    handleLogin()
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
J. D.
  • 171
  • 2
  • 13
  • You can handle the event as in three_pineapples answer here: https://stackoverflow.com/questions/24532043/proper-way-to-handle-the-close-button-in-a-main-window-pyqt-red-x/42969627 – sudobangbang Aug 16 '19 at 19:15
  • Neither of those solves what I want to do. I want the window to keep opening when the entry is incorrect. However, if the user clicks on the "X", destroy the window. Right now, it only destroys the window. – J. D. Aug 16 '19 at 19:25

2 Answers2

0

A more complete example showing how to write a login dialog is given here:


However, in your own example, you should note that It's not necessary to handle the close-event, because the "X" button will automatically set the dialog's result to Rejected. Instead, you just need to set the result to Accepted when the submit button is clicked. You can then check the return value of exec_() to see what the user did.

Here is a re-write of your script that does that:

import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

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

        self.grid = QGridLayout(self)
        self.setGeometry(650, 350, 400, 150)
        self.setFixedSize(400, 150)

        self.UserLabels = QLabel(self)
        self.UserLabels.setText('Login Number:')
        self.grid.addWidget(self.UserLabels, 0, 0, 1, 1)

        self.textName = QLineEdit(self)
        self.grid.addWidget(self.textName, 0, 1, 1, 2)

        self.buttonLogin = QPushButton('Submit', self)
        self.buttonLogin.clicked.connect(self.accept)
        self.grid.addWidget(self.buttonLogin, 2, 0, 1, 3)

    def password(self):
        return self.textName.text()

def handleLogin():
    result = None
    login = Login()
    while result is None:
        if login.exec_() == QDialog.Accepted:
            password = login.password()
            if password == '6':
                result = True
        else:
            result = False
    return result

if __name__ == '__main__':
    app = QApplication(sys.argv)
    if handleLogin():
        print('logged in')
    else:
        print('cancelled')
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • It's also possible to override `exec_()`, and directly return the password using `if super(Login, self).exec_(): return self.textName.text()`, which is similar to what QInputDialog static methods do. – musicamante Aug 16 '19 at 20:43
  • 1
    @musicamante Yes, I just wanted to explain what was going wrong with the OP's code, and show how to simplify the logic. I would normally write a login dialog [something like this](https://stackoverflow.com/a/11812578/984421). – ekhumoro Aug 16 '19 at 20:51
0

Try it:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class MainWindow(QMainWindow):

    windowList = []                                          

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setWindowTitle('Main interface')
        self.showMaximized()
        # Create Menu Bar
        self.createMenus()

    def createMenus(self):
        # Create login action
        self.printAction1 = QAction(self.tr("Entrance"), self)
        self.printAction1.triggered.connect(self.on_printAction1_triggered)
        # Create exit action
        self.printAction2 = QAction(self.tr("Exit"), self)
        self.printAction2.triggered.connect(self.on_printAction2_triggered)
        # Create menu, add actions
        self.printMenu = self.menuBar().addMenu(self.tr("Entrance and Exit"))
        self.printMenu.addAction(self.printAction1)
        self.printMenu.addAction(self.printAction2)

    # Step 1: Login
    def on_printAction1_triggered(self):
        self.close()
        dialog = LoginDialog()
        if  dialog.exec_()==QDialog.Accepted:
            the_window = MainWindow()
            self.windowList.append(the_window)          # ! It is important !
            the_window.show()

    def on_printAction2_triggered(self):
        self.close()

    # Interface close event
    def closeEvent(self, event):
        print("The End")


class LoginDialog(QDialog):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setWindowTitle('Login interface')
        self.resize(250, 200)
        self.setFixedSize(self.width(), self.height())
        self.setWindowFlags(Qt.WindowCloseButtonHint)

        # Configure UI controls
        self.frame = QFrame(self)
        self.frame.resize(250, 200)
        self.verticalLayout = QVBoxLayout(self.frame)

        self.lineEdit_account = QLineEdit()
        self.lineEdit_account.setPlaceholderText("Please enter nickName (admin)")
        self.verticalLayout.addWidget(self.lineEdit_account)

        self.lineEdit_password = QLineEdit()
        self.lineEdit_password.setPlaceholderText("Please enter your password (admin)")
        self.verticalLayout.addWidget(self.lineEdit_password)

        self.pushButton_enter = QPushButton()
        self.pushButton_enter.setText("OK")
        self.verticalLayout.addWidget(self.pushButton_enter)

        self.pushButton_quit = QPushButton()
        self.pushButton_quit.setText("Cancel")
        self.verticalLayout.addWidget(self.pushButton_quit)

        # bindings button Event
        self.pushButton_enter.clicked.connect(self.on_pushButton_enter_clicked)
        self.pushButton_quit.clicked.connect(QCoreApplication.instance().quit)

    def on_pushButton_enter_clicked(self):
        # Check nickName
        if self.lineEdit_account.text() != "admin":
            return

        # Check password
        if self.lineEdit_password.text() != "admin":
            return

        # Close the dialog and return 1 when checking
        self.accept()


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

    dialog = LoginDialog()

    if  dialog.exec_()==QDialog.Accepted:
        the_window = MainWindow()
        the_window.show()
        sys.exit(app.exec_())

enter image description here

S. Nick
  • 12,879
  • 8
  • 25
  • 33