PyQt5 - Switch between two QMainWindow with stacked widget
-
when the user clicks the button "PLAY" of the window1, the button calls the function "playgame" which basically invokes the class of the window2 and is added on the stacked widget , but every time I click the button, the program crashes without displaying any specific error in the terminal.
Is there any solution ?NOTE : both files are generated by qt designer, I converted them to
py and I added some changes# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'game_flag.ui' # # Created by: PyQt5 UI code generator 5.15.4 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtWidgets import sys from window2 import gameart class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(889, 680) MainWindow.setStyleSheet("background-color : #161219;") MainWindow.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(260, 300, 381, 141)) self.pushButton.setStyleSheet("QPushButton{\n" " border: 4px groove #BC006C;\n" " border-radius: 20px;\n" " color:white;\n" " font: 20pt \"Lexend SemiBold\";\n" "}\n" "QPushButton:hover{\n" " background-color : #800048;\n" " \n" "}\n" "") self.pushButton.setObjectName("pushButton") self.pushButton.clicked.connect(self.playgame) #when clicked, calls the function playgame MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "PLAY")) def playgame(self): #call the mainwindow of window2 secondwindow = gameart().start() widget.addWidget(secondwindow) widget.setCurrentIndex(secondwindow) class gameintro(): def __init__(self): app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_()) if __name__ == "__main__": firstwindow = gameintro() widget = QtWidgets.QStackedWidget() widget.addWidget(firstwindow) #add the mainwindow of window1 to the stackwidget widget.setCurrentIndex(firstwindow)
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'game_flag.ui' # # Created by: PyQt5 UI code generator 5.15.4 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtWidgets import sys class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(889, 680) MainWindow.setStyleSheet("background-color : #161219;") MainWindow.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.centralwidget = QtWidgets.QWidget(MainWindow) MainWindow.setCentralWidget(self.centralwidget) self.centralwidget.setObjectName("centralwidget") QtCore.QMetaObject.connectSlotsByName(MainWindow) self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(260, 300, 381, 141)) self.pushButton.setStyleSheet("QPushButton{\n" " border: 4px groove #BC006C;\n" " border-radius: 20px;\n" " color:white;\n" " font: 20pt \"Lexend SemiBold\";\n" "}\n" "QPushButton:hover{\n" " background-color : #800048;\n" " \n" "}\n" "") self.pushButton.setObjectName("pushButton") self.retranslateUi(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle("Country Game") self.pushButton.setText(_translate("MainWindow", "TEST")) class gameart(): def start(self): app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() app.exec_()
-
@Bored-Nerd said in PyQt5 - Switch between two QMainWindow with stacked widget:
but every time I click the button, the program crashes without displaying any specific error in the terminal.
I don't know what you are doing with multiple main windows, stacked widgets and so on. But your
window1.py
creates aQApplication
ingameintro.__init__()
and yourwindow2.py
has agameart.start()
which you call and that also creates aQApplication
. Which for sure is wrong (you can only have one instance of aQApplication
), and will crash or otherwise misbehave.I would not hazard to tell you what you should do as I do not follow any of your logic.
BTW, the only thing that makes sense would be to have one
QMainWindow
in your application. That could contain aQStackedWidget
which you use to display alternative content in that main window. -
@JonB
these 2 files are the simplified version of the 2 original files which they contains a lot of code that has nothing to do with the problem .
My logic here is : once the user clicks the button "Play" , stacked widget adds the mainwindow of window2 and set its index and the mainwindow of the window2 will be display to the user.
About your last comment, is it possible to have one QMainWindow with 2 classes? I tried implementing it but it crashes -
@Bored-Nerd
Since this is not your actual code it is not possible to comment on why it crashes. Your "simplified" code contains two places where you create aQApplication
, and if you have that it is wrong. And you havesecondwindow = gameart().start()
, which does not even return a value, and certainly not a window. In itself having multipleQMainWindow
s would not crash. -
Yes, in the 2 original files there are 2 QApplication, but still crashes even though I deleted the QApplication of window2
-
Hi,
You can have as many QMainWindow as you want, it just does not make much sense.
As for your design, the main issue is that your gameart and gameintro class/function do mostly the same thing so at some point you are creating two instances of QApplication which is wrong.
You should clean that logic first. Also, there is no need for classes for such functions.
-
@Bored-Nerd
What would you like us to say? We cannot tell you why what crashes when you freely admit this is not your actual code.In any case, you need to redesign your code from anything like what it is now for it to make sense.
-
@JonB Like I said before, these 2 files are the "simplified" version of the 2 original files. I'm testing with stackedwidget but it doesn't work. It doesn't make any difference if I upload the whole code. I am here because I am trying to figure out if it's possible to use stackedwidget with 2 QMainWindow (and if it makes sense or not) and from what I understood there must be one QApplication and QMainWindow.
-
No, as already written, you can have as many QMainWindow you want.
QApplication must be unique.
It does not really make sense to use several QMainWindow in a given application but that is up to you.
Did you try to run your application with gdb to find exactly where it crashes ?
You might also want to do some testing with widgets built only in code rather than with designer.
-
@Bored-Nerd
Yes it is possible to have aQStackedWidget
which alternates between twoQMainWindow
s if that is what you want.You would have a main program, with a single
QApplicaton
, and with theQStackedWidget
. There you should create the two separateQMainWindow
instances and put them both into theQStackedWidget
. Only the first will be shown at this point. Upon pressing a button in one of these, the stacked widget should change its index to show the otherQMainWindow
instance. Then your issue is that the button press signal in eitherQMainWindow
should have its slot where theQStackedWidget
is so that can change the active index for which main window to show.