Skip to content Skip to sidebar Skip to footer

How To Make Nested Stackedlayouts In Pyqt5?

I am creating a PyQt5 application in Python for a university project that uses QStackedLayout to make it a single-windowed app, however, I can not figure out how to nest a Stacked

Solution 1:

enter image description here You can add a QStackedWidget to the right of the QListWidget and control the chosen list object with the currentRowChanged signal. I would recommend you use QHBoxLayout, QVBoxLayout, or QGridLayout for layout management.

import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, 
                             QLabel, QPushButton, QWidget,
                             QStackedLayout, QListWidget,
                             QVBoxLayout, QStackedWidget,
                             QGridLayout)
from PyQt5.QtCore import QRect, Qt

classUi(QWidget):

    defsetupUi(self, Main):

        Main.setObjectName("Main")
        Main.setFixedSize(900, 500)

        self.width = 900
        self.height = 500

        self.setFixedSize(self.width, self.height)

        '''MENU ON THE MAIN WINDOW'''
        self.menu = QStackedLayout()

        self.mainMenu = QWidget()
        self.howToMenu = QWidget()

        self.mainMenuUi()
        self.howToMenuUi()

        self.menu.addWidget(self.mainMenu)
        self.menu.addWidget(self.howToMenu)

        '''MENU ON THE HOWTO WINDOW'''#self.howToMenuMenu = QStackedLayout()#self.howToOverView    = QWidget()#self.howToLevel       = QWidget()#self.howToTapeMeasure = QWidget()#self.howToTheodolite  = QWidget()#self.   overViewUi()#self.      levelUi()#self.tapeMeasureUi()#self. theodoliteUi()#self.howToMenuMenu.addWidget(self.howToOverView   )#self.howToMenuMenu.addWidget(self.howToLevel      )#self.howToMenuMenu.addWidget(self.howToTapeMeasure)#self.howToMenuMenu.addWidget(self.howToTheodolite )defmainMenuUi(self):

        self.mainMenu.setFixedSize(self.width, self.height)

        self.mainMenuText = QLabel(self.mainMenu)
        self.mainMenuText.setGeometry(QRect(30, 120, 480, 200))
        self.mainMenuText.setStyleSheet("font: 14pt Century Gothic")
        self.mainMenuText.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
        self.mainMenuText.setText("Welcome to the Surveying Traverse Calculator!")

        self.howToButton = QPushButton("HOW TO DO A TRAVERSE", self.mainMenu)

        self.howToButton.setGeometry(140, 180, 200, 30)

    defhowToMenuUi(self):

        self.howToMenu_layout = QGridLayout()

        self.howToMenu.setFixedSize(self.width, self.height)

        self.menuButton1 = QPushButton("Back to main menu")
        self.menuButton1.setGeometry(QRect(10, 10, 200, 30))

        self.howToTitle = QLabel()
        self.howToTitle.setGeometry(QRect(10, 50, self.width, 40))
        self.howToTitle.setStyleSheet("font: 14pt Century Gothic")
        self.howToTitle.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignVCenter)
        self.howToTitle.setText("How to Do a Traverse")

        self.howToSteps = QListWidget()
        self.howToSteps.setGeometry(QRect(10, 100, 200, 80))
        self.howToSteps.insertItem(0, "OVERVIEW"    )
        self.howToSteps.insertItem(1, "LEVEL"       )
        self.howToSteps.insertItem(2, "TAPE MEASURE")
        self.howToSteps.insertItem(3, "THEODOLITE"  )
        self.howToSteps.currentRowChanged.connect(self.display_traverse)

        self.overview_container = QWidget()
        self.level_container = QWidget()
        self.tape_measure_container = QWidget()
        self.theodolite_container = QWidget()

        self.overViewUi()
        self.levelUi()
        self.tapeMeasureUi()
        self.theodoliteUi()

        self.traverse_action = QStackedWidget()
        self.traverse_action.addWidget(self.overview_container) 
        self.traverse_action.addWidget(self.level_container) 
        self.traverse_action.addWidget(self.tape_measure_container) 
        self.traverse_action.addWidget(self.theodolite_container) 
        self.traverse_action.setCurrentIndex(0)

        self.howToMenu_left_layout = QVBoxLayout()
        self.howToMenu_left_layout.addWidget(self.menuButton1)
        self.howToMenu_left_layout.addWidget(self.howToTitle)
        self.howToMenu_left_layout.addWidget(self.howToSteps)

        self.howToMenu_layout.addLayout(self.howToMenu_left_layout,0,0,1,1)
        self.howToMenu_layout.addWidget(self.traverse_action,0,1,1,1)
        self.howToMenu.setLayout(self.howToMenu_layout)

    defoverViewUi(self):
        self.overview_layout = QVBoxLayout()
        self.overview_button = QPushButton('Overview')
        self.overview_layout.addWidget(self.overview_button)
        self.overview_container.setLayout(self.overview_layout)

    deflevelUi(self):
        self.level_layout = QVBoxLayout()
        self.level_button = QPushButton('Level')
        self.level_layout.addWidget(self.level_button)
        self.level_container.setLayout(self.level_layout)

    deftapeMeasureUi(self):
        self.tape_measure_layout = QVBoxLayout()
        self.tape_measure_button = QPushButton('Tape measure')
        self.tape_measure_layout.addWidget(self.tape_measure_button)
        self.tape_measure_container.setLayout(self.tape_measure_layout)

    deftheodoliteUi(self):
        self.theodolite_layout = QVBoxLayout()
        self.theodolite_button = QPushButton('Theodolite')
        self.theodolite_layout.addWidget(self.theodolite_button)
        self.theodolite_container.setLayout(self.theodolite_layout)

    defdisplay_traverse(self, index):
        self.traverse_action.setCurrentIndex(index)

classMain(QMainWindow, Ui):

    def__init__(self):

        super(Main, self).__init__()

        self.setupUi(self)

        self.menuButton1.clicked.connect(self.menuWindow)
        self.howToButton.clicked.connect(self.howToWindow)

    defmenuWindow(self):

        self.menu.setCurrentIndex(0)

    defhowToWindow(self):

        self.menu.setCurrentIndex(1)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    M = Main()
    sys.exit(app.exec())

Solution 2:

In the following example a QHBoxLayout is placed in the centralwidget, and as a first element the QListWidget and as a second element the QStackedLayout. To make the change I use the currentRowChanged signal from QListWidget

from PyQt5 import QtCore, QtGui, QtWidgets


classMainWindow(QtWidgets.QMainWindow):
    def__init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        hlay = QtWidgets.QHBoxLayout(central_widget)

        self.overview_widget = QtWidgets.QWidget()
        self.fill_overview()
        self.level_widget = QtWidgets.QWidget()
        self.fill_level()
        self.tape_measure_widget = QtWidgets.QWidget()
        self.fill_tape_measure()
        self.theodolite_widget = QtWidgets.QWidget()
        self.fill_theodolite()

        self.list_widget = QtWidgets.QListWidget()

        self.slay = QtWidgets.QStackedLayout()
        hlay.addWidget(self.list_widget)
        hlay.addLayout(self.slay)
        hlay.setStretch(0, 0)
        hlay.setStretch(1, 1)

        self.list_widget.currentRowChanged.connect(self.slay.setCurrentIndex)

        for w, text in (
            (self.overview_widget, "OVERVIEW"),
            (self.level_widget, "LEVEL"),
            (self.tape_measure_widget, "TAPE MEASURE"),
            (self.theodolite_widget, "THEODOLITE"),
        ):
            self.slay.addWidget(w)
            self.list_widget.addItem(text)

    deffill_overview(self):
        hlay = QtWidgets.QVBoxLayout(self.overview_widget)
        hlay.addWidget(
            QtWidgets.QLabel("Overview", alignment=QtCore.Qt.AlignCenter)
        )
        self.overview_widget.setStyleSheet("background-color:green;")

    deffill_level(self):
        hlay = QtWidgets.QVBoxLayout(self.level_widget)
        hlay.addWidget(
            QtWidgets.QLabel("Level", alignment=QtCore.Qt.AlignCenter)
        )
        self.level_widget.setStyleSheet("background-color:blue;")

    deffill_tape_measure(self):
        hlay = QtWidgets.QVBoxLayout(self.tape_measure_widget)
        hlay.addWidget(
            QtWidgets.QLabel("Tape Measure", alignment=QtCore.Qt.AlignCenter)
        )
        self.tape_measure_widget.setStyleSheet("background-color:red;")

    deffill_theodolite(self):
        hlay = QtWidgets.QVBoxLayout(self.theodolite_widget)
        hlay.addWidget(
            QtWidgets.QLabel("Theodolite", alignment=QtCore.Qt.AlignCenter)
        )
        self.theodolite_widget.setStyleSheet("background-color:gray;")


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.resize(640, 240)
    w.show()
    sys.exit(app.exec_())

Post a Comment for "How To Make Nested Stackedlayouts In Pyqt5?"