Skip to content

Instantly share code, notes, and snippets.

@MalloyDelacroix
Last active July 4, 2023 09:05
Show Gist options
  • Star 58 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save MalloyDelacroix/2c509d6bcad35c7e35b1851dfc32d161 to your computer and use it in GitHub Desktop.
Save MalloyDelacroix/2c509d6bcad35c7e35b1851dfc32d161 to your computer and use it in GitHub Desktop.
A PyQt5 example of how to switch between multiple windows.
import sys
from PyQt5 import QtCore, QtWidgets
class MainWindow(QtWidgets.QWidget):
switch_window = QtCore.pyqtSignal(str)
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.setWindowTitle('Main Window')
layout = QtWidgets.QGridLayout()
self.line_edit = QtWidgets.QLineEdit()
layout.addWidget(self.line_edit)
self.button = QtWidgets.QPushButton('Switch Window')
self.button.clicked.connect(self.switch)
layout.addWidget(self.button)
self.setLayout(layout)
def switch(self):
self.switch_window.emit(self.line_edit.text())
class WindowTwo(QtWidgets.QWidget):
def __init__(self, text):
QtWidgets.QWidget.__init__(self)
self.setWindowTitle('Window Two')
layout = QtWidgets.QGridLayout()
self.label = QtWidgets.QLabel(text)
layout.addWidget(self.label)
self.button = QtWidgets.QPushButton('Close')
self.button.clicked.connect(self.close)
layout.addWidget(self.button)
self.setLayout(layout)
class Login(QtWidgets.QWidget):
switch_window = QtCore.pyqtSignal()
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.setWindowTitle('Login')
layout = QtWidgets.QGridLayout()
self.button = QtWidgets.QPushButton('Login')
self.button.clicked.connect(self.login)
layout.addWidget(self.button)
self.setLayout(layout)
def login(self):
self.switch_window.emit()
class Controller:
def __init__(self):
pass
def show_login(self):
self.login = Login()
self.login.switch_window.connect(self.show_main)
self.login.show()
def show_main(self):
self.window = MainWindow()
self.window.switch_window.connect(self.show_window_two)
self.login.close()
self.window.show()
def show_window_two(self, text):
self.window_two = WindowTwo(text)
self.window.close()
self.window_two.show()
def main():
app = QtWidgets.QApplication(sys.argv)
controller = Controller()
controller.show_login()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
@jayrawatrj
Copy link

In the Login class instead of only login button, i have added two text box for username and password then i want to go to another window when i will click on login button but when i click on login button it gets exit from program.. please help me.
here's my code..
annotation
annotation 1

@Panos26
Copy link

Panos26 commented Jan 8, 2019

How can I make the same thinf but with multiple windows?
Like a game menu and every button opens a different window..???

++ The window that is closed still runs on the background...why?

@cvailbf
Copy link

cvailbf commented May 29, 2019

Use X.hide() instead of X.close() to make the windows disappear.

@soumilshah1995
Copy link

soumilshah1995 commented Jun 4, 2019

Hello My name is Soumil Shah I am making a project with PyQt5 and Stuck on Changing pages the problem is i am able to switch from page one to page two when i go back when i use hide method it gives me error can you help me i am trying to implement your login in my code but due to some error i am not able to do that here is my code

looking foreward to hear from you
regards
Shah

`
from PyQt5 import QtCore, QtGui, QtWidgets
import sys

class Ui_Form1(object):
switch_window = QtCore.pyqtSignal(str)

def setupUi(self, Form):
    Form.setObjectName("Form")
    Form.resize(408, 317)
    self.pushButton = QtWidgets.QPushButton(Form)
    self.pushButton.setGeometry(QtCore.QRect(140, 180, 113, 32))
    self.pushButton.setObjectName("pushButton")
    self.label = QtWidgets.QLabel(Form)
    self.label.setGeometry(QtCore.QRect(100, 30, 201, 71))
    self.label.setObjectName("label")

    self.retranslateUi(Form)
    QtCore.QMetaObject.connectSlotsByName(Form)
    self.pushButton.clicked.connect(self.pushbutton_handler)


def pushbutton_handler(self):
    self.openwindow()

def retranslateUi(self, Form):
    _translate = QtCore.QCoreApplication.translate
    Form.setWindowTitle(_translate("Form", "Form"))
    self.pushButton.setText(_translate("Form", "Back"))
    self.label.setText(_translate("Form", "Page 1"))

class Ui_Form(object):

switch_window = QtCore.pyqtSignal(str)

def setupUi(self, Form):
    Form.setObjectName("Form")
    Form.resize(522, 355)
    self.label = QtWidgets.QLabel(Form)
    self.label.setGeometry(QtCore.QRect(140, 10, 191, 51))
    self.label.setStyleSheet("font: 36pt \".SF NS Text\";")
    self.label.setObjectName("label")
    self.pushButton = QtWidgets.QPushButton(Form)
    self.pushButton.setGeometry(QtCore.QRect(190, 160, 113, 32))
    self.pushButton.setObjectName("pushButton")

    self.retranslateUi(Form)
    QtCore.QMetaObject.connectSlotsByName(Form)
    self.pushButton.clicked.connect(self.pushbutton_handler)


def pushbutton_handler(self):
    self.switch_window.emit()


def retranslateUi(self, Form):
    _translate = QtCore.QCoreApplication.translate
    Form.setWindowTitle(_translate("Form", "Form"))
    self.label.setText(_translate("Form", "Main Page"))
    self.pushButton.setText(_translate("Form", "Next"))

class Controller:

def __init__(self):
    pass

def show_login(self):
    self.login = Ui_Form()
    self.login.switch_window.connect(self.show_main)
    self.login.show()

def show_main(self):
    self.window = Ui_Form1()
    self.window.switch_window.connect(self.show_login)
    self.login.close()
    self.window.show()

def main():
app = QtWidgets.QApplication(sys.argv)
controller = Controller()
controller.show_login()
sys.exit(app.exec_())

if name == 'main':
main()

`

@MalloyDelacroix
Copy link
Author

There are quite a few problems here. The code, as you posted it, would not run at all for me, so I cannot see exactly where you are getting an error. I changed it in the following way:

from PyQt5 import QtCore, QtGui, QtWidgets
import sys


class Ui_Form1(object):

    # switch_window = QtCore.pyqtSignal(str)

    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(408, 317)
        self.pushButton = QtWidgets.QPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(140, 180, 113, 32))
        self.pushButton.setObjectName("pushButton")
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(100, 30, 201, 71))
        self.label.setObjectName("label")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)
        # self.pushButton.clicked.connect(self.pushbutton_handler)

    # def pushbutton_handler(self):
    #     self.openwindow()

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.pushButton.setText(_translate("Form", "Back"))
        self.label.setText(_translate("Form", "Page 1"))


class Ui_Form(object):

    # switch_window = QtCore.pyqtSignal(str)

    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(522, 355)
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(140, 10, 191, 51))
        self.label.setStyleSheet("font: 36pt \".SF NS Text\";")
        self.label.setObjectName("label")
        self.pushButton = QtWidgets.QPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(190, 160, 113, 32))
        self.pushButton.setObjectName("pushButton")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)
        # self.pushButton.clicked.connect(self.pushbutton_handler)

    # def pushbutton_handler(self):
    #     self.switch_window.emit()

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.label.setText(_translate("Form", "Main Page"))
        self.pushButton.setText(_translate("Form", "Next"))


class Login(QtWidgets.QWidget, Ui_Form):

    switch_window = QtCore.pyqtSignal()

    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.setupUi(self)

        self.pushButton.clicked.connect(self.pushbutton_handler)

    def pushbutton_handler(self):
        self.switch_window.emit()


class MainWindow(QtWidgets.QWidget, Ui_Form1):

    switch_window = QtCore.pyqtSignal()

    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.setupUi(self)

        self.pushButton.clicked.connect(self.pushbutton_handler)

    def pushbutton_handler(self):
        self.switch_window.emit()


class Controller:

    def __init__(self):
        pass

    def show_login(self):
        self.login = Login()
        self.login.switch_window.connect(self.show_main)
        self.login.show()

    def show_main(self):
        self.window = MainWindow()
        self.window.switch_window.connect(self.show_login)
        self.login.close()
        self.window.show()


def main():
    app = QtWidgets.QApplication(sys.argv)
    controller = Controller()
    controller.show_login()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

As you can see, I have taken the classes generated via the pyuic tool and made other classes that inherit from both QWidget and the auto generated classes. These new classes are the ones where the GUI programming should be done. You should not add additional code to the files generated by pyuic because if you were to change your UI with Qt Designer and run pyuic again, all of the code you added would be overwritten.

I have commented out the portions of the generated classes that I believe you added so they do not affect the new classes. The only other change I made here is in the pyqtSignal. In my example these signals emitted a string, but only to demonstrate how to pass information from one window to another. It appears that you were trying to emit these signals without supplying them with a string. This is the only area I found that caused an error. You did however say that the error occurred when you called the hide() method, but you do not call that method anywhere in the code you posted.

@soumilshah1995
Copy link

hello there,
First of all, i want to thank you for such a quick Response I didn't expect such a quick response. I want to say thanks to you for taking out time and reading my code and helping me out a very handful of programmers do that. thanks for the advice that I should not write any code in that instead create a class that inherits from above two class.

Once again I am saying thanks to you
Just curious to know from which country are you from?

@MalloyDelacroix
Copy link
Author

You're welcome, I'm glad I could help. I'm from the U.S.

@soumilshah1995
Copy link

soumilshah1995 commented Jun 6, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment