Unable to see widgets on second window after successful login. Python and PyQt4
Question: There are two classes for two windows. Upon successful login it should launch
MainWindow. Code is able to launch MainWindow. But does not show any widgets
on it. There are two catergories of users: 1) admin 2) Other user I want to
show two different windows for admin and other user. how to fix above problem?

    
    
    from PyQt4 import QtGui
    import sys
    
    class LoginDialog(QtGui.QDialog):
        '''This is login window class'''
        def __init__(self):
            super().__init__()
    
            self.username = QtGui.QLineEdit()
            self.password = QtGui.QLineEdit()
    
            self.login = QtGui.QPushButton('Login')
            self.reset = QtGui.QPushButton('Reset')
    
            loginLayout = QtGui.QFormLayout()
            loginLayout.addRow("Username", self.username)
            loginLayout.addRow("Password", self.password)
            loginLayout.addRow(self.login, self.reset)
    
            self.login.clicked.connect(self.onlogin)
            self.reset.clicked.connect(self.onreset)
            self.setGeometry(200,200,500,300)
            self.setWindowTitle('test')
            self.setWindowIcon(QtGui.QIcon('pythonlogo.png'))
    
    ##      layout = QtGui.QVBoxLayout()
    ##
    ##      layout.addLayout(loginLayout)
    ##      layout.addWidget(self.buttons)
            self.setLayout(loginLayout)
            self.show()
    
        def onlogin(self):
            ''''When login button is pressed '''
            uname = str(self.username.text())
            pwd = str(self.password.text())
            if  uname == 'admin' and pwd == 'someone':
                self.accept()
            else:
                QtGui.QMessageBox.warning(self, 'Error', 'incorrect cred')
    
        def onreset(self):
            '''When reset button is called '''
            self.username.setText('')
            self.password.setText('')
    
    class MainWindow(QtGui.QMainWindow):
        '''This is main window class'''
        def __init__(self):
            super(MainWindow, self).__init__()
            self.setGeometry(200,200,500,300)
            self.home()
            # print('yetotofnck nkdfnk')
    
            # self.label = QtGui.QLabel()
            # self.setCentralWidget(self.label)
    
            self.searchbar = QtGui.QLineEdit()
            self.searchbtn = QtGui.QPushButton('Search')
            self.logoutbtn = QtGui.QPushButton('Logout')
    
            self.searchbtn.clicked.connect(self.onsearch)
            self.logoutbtn.clicked.connect(self.onlogout)
    
    
            self.layout = QtGui.QFormLayout()
            self.layout.addRow(self.searchbar, self.searchbtn)
            self.layout.addRow(self.logoutbtn)
    
    ##      wlayout = QtGui.QVBoxLayout()
    ##      wlayout.addLayout(layout)
            self.setLayout(self.layout)
    
        def home(self):
    
            btn = QtGui.QPushButton('Logout')
            btn.clicked.connect(self.close_app)
            self.show()
    
        def close_app(self):
    
            sys.exit(-1)
    
        def onsearch(self):
            print('serach successful')
    
        def onlogout(self):
            pass
    
        def setusername(self, 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_():
            sys.exit(-1)
    
        main = MainWindow()
        main.home()
    ##  main.setusername(login.username.text())
    ##  main.show()
    
        sys.exit(app.exec_())
    


Answer: `QMainWindow` is a specialized window that has its own layout by default, so
you should be seeing a warning:

> QWidget::setLayout: Attempting to set QLayout "" on MainWindow "", which
> already has a layout

See the [QMainWindow docs](http://doc.qt.io/qt-4.8/qmainwindow.html#details)
for a description of the layout.

If you want to use a FormLayout, then use a QWidget as your main window:

> A widget that is not embedded in a parent widget is called a window

See the [QWidget docs](http://doc.qt.io/qt-4.8/qwidget.html#details).

Here's an example:

> **On OSX** 10.10.5 with Qt 4.8.6, PyQt 4.11.4, and python 2.7, the code
> below produces the warning:
>

>> modalSession has been exited prematurely - check for a reentrant call to
endModalSession:

>
> Apparently that is a bug. See <https://bugreports.qt.io/browse/QTBUG-37699>.
> With Qt 5.6.0, PyQt 5.5.1, python3.4, I don't see that warning.
    
    
    from PyQt4.QtGui import (QMainWindow, QDialog, QApplication, 
            QLineEdit, QPushButton, QFormLayout, QMessageBox, QWidget)
    #from PyQt5.QtWidgets import (QMainWindow, QDialog, QApplication, 
    #        QLineEdit, QPushButton, QFormLayout, QMessageBox, QWidget)
    
    from PyQt4.QtCore import pyqtSignal
    #from PyQt5.QtCore import pyqtSignal
    import sys
    
    class LoginDialog(QDialog):
    
        loginSignal = pyqtSignal(str, str) #Create a custom signal, which you can use
                                           #to send two string arguments to a connected function.
    
        def __init__(self, mainWindow):
            super(LoginDialog, self).__init__()
    
            self.setGeometry(200,200,500,300)
            self.setWindowTitle('Login')
    
            self.usernameInput = QLineEdit()
            self.passwordInput = QLineEdit()
            self.loginButton = QPushButton('Login')
            self.resetButton = QPushButton('Reset')
    
            #*****> CONNECT BUTTON TO A FUNCTION THAT EMITS CUSTOM SIGNAL <*****
            self.loginButton.clicked.connect(self.emitLoginSignal)
            self.resetButton.clicked.connect(self.onclickReset)
    
            loginLayout = QFormLayout()
            loginLayout.addRow("Username", self.usernameInput)
            loginLayout.addRow("Password", self.passwordInput)
            loginLayout.addRow(self.loginButton, self.resetButton)
            self.setLayout(loginLayout)
    
        def emitLoginSignal(self):
            #***> EMIT CUSTOM SIGNAL <****
            self.loginSignal.emit(
                self.usernameInput.text(),
                self.passwordInput.text()
            )
    
    
        def onclickReset(self):
            pass
    
    
    class MyAdminWindow(QWidget):
    
        def __init__(self):
            super(MyAdminWindow, self).__init__()
    
            self.setGeometry(200,200,500,300)
            self.setWindowTitle("MainWindow")
    
            self.searchbar = QLineEdit()
            self.searchbtn = QPushButton('Search')
            self.logoutbtn = QPushButton('Logout')
    
            self.searchbtn.clicked.connect(self.onsearch)
            self.logoutbtn.clicked.connect(self.onlogout)
    
            formLayout = QFormLayout()
            formLayout.addRow(self.searchbar, self.searchbtn)
            formLayout.addRow(self.logoutbtn)
            self.setLayout(formLayout)
    
            self.loginDialog = LoginDialog(self)
            #*****> CONNECT TO CUSTOM SIGNAL HERE: <*******
            self.loginDialog.loginSignal.connect(self.validateUser)
            self.loginDialog.exec_()
    
        def onsearch(self):
            pass
        def onlogout(self):
            pass
    
    
        def validateUser(self, username, password):
            if  username == 'admin' and password == 'someone':
                self.loginDialog.close()
                self.show()  #Now show the window.
            else:
                QMessageBox.warning(self, 'Error', 'incorrect cred')
    
    
    app = QApplication([])
    window = MyAdminWindow()
    #Don't show() the window
    sys.exit(app.exec_())
    

