16

I nearly finished my application, when the customer asked if I could implement some kind of login form on application startup.

So far I have designed the UI, and tinkered about the actual execution. Username and password are irrelevant for now.

class Login(QtGui.QDialog):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.ui=Ui_dlgLogovanje()
        self.ui.setupUi(self)

        QtCore.QObject.connect(self.ui.buttonLogin, QtCore.SIGNAL("clicked()"), self.doLogin)

    def doLogin(self):
        name = str(self.ui.lineKorisnik.text())
        passwd = str(self.ui.lineSifra.text())
        if name == "john" and passwd =="doe":
            self.runIt()
        else:
            QtGui.QMessageBox.warning(self, 'Greška',
        "Bad user or password", QtGui.QMessageBox.Ok)           

    def runIt(self):
        myprogram = Window()        
        myprogram.showMaximized() #myprogram is

class Window(QtGui.QMainWindow):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.ui=Ui_MainWindow()
        self.ui.setupUi(self)


if __name__=="__main__":
    program = QtGui.QApplication(sys.argv)
    myprogram = Window()
    if Login().exec_() == QtGui.QDialog.Accepted:       
        sys.exit(program.exec_())

Login form is shown. If correct username and password are entered, then main window is shown and working. But, the login form stays active, and if I close it, the main window will also close.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
ivica
  • 1,388
  • 1
  • 22
  • 38
  • 4
    btw, `QtCore.QObject.connect(self.ui2.buttonLogin, QtCore.SIGNAL("clicked()"), self.doLogin)` can be replaced with `self.ui2.buttonLogin.clicked.connect(self.doLogin)` – warvariuc Aug 05 '12 at 06:55

1 Answers1

46

A QDialog has its own event loop, so it can be run separately from the main application.

You just need to check the dialog's return code to decide whether the main application should be run or not.

Example code (PyQt5):

from PyQt5 import QtWidgets
# from mainwindow import Ui_MainWindow

class Login(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(Login, self).__init__(parent)
        self.textName = QtWidgets.QLineEdit(self)
        self.textPass = QtWidgets.QLineEdit(self)
        self.buttonLogin = QtWidgets.QPushButton('Login', self)
        self.buttonLogin.clicked.connect(self.handleLogin)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.textName)
        layout.addWidget(self.textPass)
        layout.addWidget(self.buttonLogin)

    def handleLogin(self):
        if (self.textName.text() == 'foo' and
            self.textPass.text() == 'bar'):
            self.accept()
        else:
            QtWidgets.QMessageBox.warning(
                self, 'Error', 'Bad user or password')

class Window(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        # self.ui = Ui_MainWindow()
        # self.ui.setupUi(self)

if __name__ == '__main__':

    import sys
    app = QtWidgets.QApplication(sys.argv)
    login = Login()

    if login.exec_() == QtWidgets.QDialog.Accepted:
        window = Window()
        window.show()
        sys.exit(app.exec_())

Example code (PyQt4):

from PyQt4 import QtGui
# from mainwindow import Ui_MainWindow

class Login(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Login, self).__init__(parent)
        self.textName = QtGui.QLineEdit(self)
        self.textPass = QtGui.QLineEdit(self)
        self.buttonLogin = QtGui.QPushButton('Login', self)
        self.buttonLogin.clicked.connect(self.handleLogin)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.textName)
        layout.addWidget(self.textPass)
        layout.addWidget(self.buttonLogin)

    def handleLogin(self):
        if (self.textName.text() == 'foo' and
            self.textPass.text() == 'bar'):
            self.accept()
        else:
            QtGui.QMessageBox.warning(
                self, 'Error', 'Bad user or password')

class Window(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        # self.ui = Ui_MainWindow()
        # self.ui.setupUi(self)    

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    login = Login()

    if login.exec_() == QtGui.QDialog.Accepted:
        window = Window()
        window.show()
        sys.exit(app.exec_())
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • Thank you for your reply, it works.What if I wanted to check, lets say that two variables equal to something, and if they do, then emit a signal? if name == "john" and passw == "doe": self.emit(something goes here) – ivica Aug 05 '12 at 00:40
  • 1
    This example creates a temp dialog that gets thrown away so you cant check more values. You probably want to do login = Login(); login.exec_() And check the return of that for accepted. And then you can continue to check attributes on the login object. – jdi Aug 05 '12 at 06:17
  • Well, we got somewhere :) I have edited the original posting with new code, so that it can be read more clearly. – ivica Aug 05 '12 at 10:21
  • 1
    @ivica. I've updated my answer with a more complete example. Note how my `Login` class can work completely indepenently from the application it is used with, allowing for code re-use. – ekhumoro Aug 05 '12 at 16:17
  • I finally got it. My code has lots of errors, mainly "parent-child" related. What would I do without SO? :) Thank you sir. – ivica Aug 05 '12 at 22:27