PyQt5 Problem involving QMainWindow class, QAction and probably the setCentralWidget() function, what to do?

22 Views Asked by At

Good afternoon. This is an MRE of the problem that you can easily run in your machine

import sys

from PyQt5.QtWidgets import (
    QWidget, QMenuBar, QMenu, QApplication,
    QAction, QMainWindow,
    QVBoxLayout, QLabel
)


class mainwindow(QMainWindow):

    def __init__(self, screen2, screen3):
        super().__init__()

        self._screen2 = screen2
        self._screen3 = screen3

        self.tela()
        self.acoes()
        self.sinais()

    def tela(self):

        layout = QVBoxLayout()
        label = QLabel('screen 1')
        layout.addWidget(label)
        widget_central = QWidget()
        self.setCentralWidget(widget_central)
        widget_central.setLayout(layout)

    def acoes(self):

        self.action_screen2 = QAction('screen 2')
        self.action_screen3 = QAction('screen 3')

        menu_opt = QMenuBar(self)
        self.setMenuBar(menu_opt)
        menu = QMenu("avaliable screens", self)
        menu_opt.addMenu(menu)
        screen_menu = menu.addMenu("screens")
        screen_menu.addAction(self.action_screen2)
        screen_menu.addAction(self.action_screen3)

    def sinais(self):

        self.action_screen2.triggered.connect(self.tela2)
        self.action_screen3.triggered.connect(self.tela3)

    def tela2(self):

        self.setCentralWidget(self._screen2)

    def tela3(self):

        self.setCentralWidget(self._screen3)


class widget1(QWidget):

    def __init__(self):
        super().__init__()

        self.screen()

    def screen(self):
        layout = QVBoxLayout()
        label = QLabel('screen 2')
        layout.addWidget(label)
        self.setLayout(layout)


class widget2(QWidget):

    def __init__(self):
        super().__init__()

        self.screen()

    def screen(self):
        layout = QVBoxLayout()
        label = QLabel('screen 3')
        layout.addWidget(label)
        self.setLayout(layout)


def main():

    applic = QApplication(sys.argv)
    screen2 = widget1()
    screen3 = widget2()
    app = mainwindow(screen2, screen3)
    app.show()
    sys.exit(applic.exec_())


if __name__ == '__main__':
    main()

If you run this code you'll be presented with a menu which allows you to choose from different screen options, in this sample the screens are made of a label that reads the number of the chosen screen, I'm using QActions to make the connections. Screen 1 is default, screens 2 and 3 are represented by 2 classes that inherit from QWidget and what "glue" things together is the setCentralWidget() function of the QMainWindow class.

This works for the first few changes, like: from screen1 (default) to screen2 to 3. But this only work once. Let's say that you selected screen 2 then 3, then if you want to go back to screen 2 (and vice-versa) the application will eventually crash.

What can I do to prevent the application to close itself if I want to go back to an already selected screen?

0

There are 0 best solutions below