Unable to create stacked layout PyQt5

Hello All,

I am unable to create the stacked layout from the below code snippet.

import sys

from PyQt5 import QtWidgets
from PyQt5.QtWidgets import (
    QApplication,
    QComboBox,
    QFormLayout,
    QLineEdit,
    QStackedLayout,
    QVBoxLayout,
    QWidget,
    QMainWindow,
)

class stacked(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QStackedLayout Example")
        # Create a top-level layout
        layout = QVBoxLayout()
        self.setLayout(layout)
        # Create and connect the combo box to switch between pages
        self.pageCombo = QComboBox()
        self.pageCombo.addItems(["Page 1", "Page 2"])
        self.pageCombo.activated.connect(self.switchPage)
        # Create the stacked layout
        self.stackedLayout = QStackedLayout()
        # Create the first page
        self.page1 = QWidget()
        self.page1Layout = QFormLayout()
        self.page1Layout.addRow("Name:", QLineEdit())
        self.page1Layout.addRow("Address:", QLineEdit())
        self.page1.setLayout(self.page1Layout)
        self.stackedLayout.addWidget(self.page1)
        # Create the second page
        self.page2 = QWidget()
        self.page2Layout = QFormLayout()
        self.page2Layout.addRow("Job:", QLineEdit())
        self.page2Layout.addRow("Department:", QLineEdit())
        self.page2.setLayout(self.page2Layout)
        self.stackedLayout.addWidget(self.page2)
        # Add the combo box and the stacked layout to the top-level layout
        layout.addWidget(self.pageCombo)
        layout.addLayout(self.stackedLayout)

    def switchPage(self):
        self.stackedLayout.setCurrentIndex(self.pageCombo.currentIndex())


class Window(QMainWindow):
    def __init__(self):
        super(Window, self).__init__()

        stacked()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

However, I am able to create stacked layout when I changed Window() to stacked() like below.

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = stacked()
    window.show()
    sys.exit(app.exec_())

What might be the reason in the above code where could not possible to create the stacked layout.

Any help would be appreciated. Thank you.

Regards,
maiya

You’ll want to call Window’s setCentralWidget method to make this work

Hi Albert

even after calling the setCentralWidget() also does not work. Or please let me know whether the way and where we calling the same is right otherwise?

class Window(QMainWindow):
    def __init__(self):
        super(Window, self).__init__()

        central = QtWidgets.QWidget()
        self.setCentralWidget(central)
        stacked()

This worked for me:

class Window(QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        main = stacked()
        self.setCentralWidget(main)

Great, it is working for me too.

One thing more, how can I set the placeholder text for that line edit?

like for example I want something like this

self.page1layout.setPlaceholderText('name')

is it possible for the QFormLayout widget?
Thank you.
Regards,
maiya

Not sure if I get what you mean, but you can simply provide the initial text in creating the LineEdits like
self.page1Layout.addRow("Name:", QLineEdit('write some text here'))

Yes, something similar to that. But I want it as placeholder text, since when the focus moves on to that particular linedit() we can enter the data (and automatically vanish the previously entered text - placeholder text).

But here in this case text will be displayed, so you have to remove the text manually and then enter the new text…

But whereas setPlaceholderText("enter text") will be displayed as shadow text and not required to remove that text before entering actual text.

you can use exactly that method, but on the LineEdit widget. So you have to create it a little differently, e.g. replace

self.page1Layout.addRow("Name:", QLineEdit())

by

widget = QLineEdit()
self.page1Layout.addRow("Name:", widget)

then you can call

widget.setPlaceHolderText('some text')
1 Like

Yes, that’s great!

Can it be possible to change the title of the window dynamically, means once I select/change the page from page1 to page2 the title of the window should be changed and vice versa as well.

Like below

when we select page1 from the above combo box, then the title of the window should be

This is MyPage1
similarly when we select the page2 from the combo box, it should be displayed like

This is MyPage2.

Any suggestion would be appreciated. Tahnk you.
Regards,
maiya

That’s what the method setWindowTitle is for. You call it on the MainWindow and pass in the title wou want to display

This create an instance of the stacked class and then throws it away.

Try this (untested):

class Window(QMainWindow):
    def __init__(self):
        super(Window, self).__init__()

        self.stacked_instance = stacked()

By convention class names are in CamelCase.
In this case class Stacked would be expected by most python developers.

Why are you using the old PyQt5 and not PyQt6 that is the current best version of PyQt?

Oh! is it, then let me try to use PyQt6.

By the way tried with above solution and didn’t work for me!.

class stacked(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("you are in Page1")
        # Create a top-level layout
        layout = QVBoxLayout()
        self.setLayout(layout)
        # Create and connect the combo box to switch between pages
        self.pageCombo = QComboBox()
        self.pageCombo.addItems(["Page 1", "Page 2"])
        self.pageCombo.activated.connect(self.switchPage)

        # Create the stacked layout
        self.stackedLayout = QStackedLayout()

        # Create the first page
        self.page1 = QWidget()
        self.page1Layout = QFormLayout()
        self.page1Layout.addRow("Name:", QLineEdit())
        self.page1Layout.addRow("Address:", QLineEdit())
        self.page1.setLayout(self.page1Layout)
        self.stackedLayout.addWidget(self.page1)

        # Create the second page
        self.page2 = QWidget()
        self.page2Layout = QFormLayout()
        self.page2Layout.addRow("Job:", QLineEdit())
        self.page2Layout.addRow("Department:", QLineEdit())
        self.page2.setLayout(self.page2Layout)
        self.stackedLayout.addWidget(self.page2)

        # Add the combo box and the stacked layout to the top-level layout
        layout.addWidget(self.pageCombo)
        layout.addLayout(self.stackedLayout)

    def switchPage(self):
        self.stackedLayout.setCurrentIndex(self.pageCombo.currentIndex())
        if self.pageCombo.currentIndex() == 1:
            self.setWindowTitle("Changed to Page2")
        else:
            self.setWindowTitle("Changed to Page1")

title not getting changed as and when we change/select the combo option from the combobox (page1/page2).

Regards,
maiya

You’re setting the WindowTitle of the stacked widget now, but the title of the mainwidget is shown. To be able to set that from within the stacked widget, you need to create it with the mainwindow as parent.
change
main = Stacked()
to
main = Stacked(self)
and

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

to

class Stacked:
    def __init__(self, parent):
        super().__init__(parent)

then you can call setWindowTitle on self.parent() instead of on self.

Still not able to do it!!

Please show what you tried

Here you go tested on PyQt6 for python 3.12.
Notice that you have to call setCentralWidget.
And I’m passing the mainwindow does as the parent of the widget.

import sys

from PyQt6 import QtWidgets
from PyQt6.QtWidgets import (
    QApplication,
    QComboBox,
    QFormLayout,
    QLineEdit,
    QStackedLayout,
    QVBoxLayout,
    QWidget,
    QMainWindow,
)

class Stacked(QWidget):
    def __init__(self, parent):
        super().__init__(parent)
        parent.setWindowTitle("QStackedLayout Example")
        # Create a top-level layout
        layout = QVBoxLayout()
        self.setLayout(layout)
        # Create and connect the combo box to switch between pages
        self.pageCombo = QComboBox()
        self.pageCombo.addItems(["Page 1", "Page 2"])
        self.pageCombo.activated.connect(self.switchPage)
        # Create the stacked layout
        self.stackedLayout = QStackedLayout()
        # Create the first page
        self.page1 = QWidget()
        self.page1Layout = QFormLayout()
        self.page1Layout.addRow("Name:", QLineEdit())
        self.page1Layout.addRow("Address:", QLineEdit())
        self.page1.setLayout(self.page1Layout)
        self.stackedLayout.addWidget(self.page1)
        # Create the second page
        self.page2 = QWidget()
        self.page2Layout = QFormLayout()
        self.page2Layout.addRow("Job:", QLineEdit())
        self.page2Layout.addRow("Department:", QLineEdit())
        self.page2.setLayout(self.page2Layout)
        self.stackedLayout.addWidget(self.page2)
        # Add the combo box and the stacked layout to the top-level layout
        layout.addWidget(self.pageCombo)
        layout.addLayout(self.stackedLayout)

    def switchPage(self):
        self.stackedLayout.setCurrentIndex(self.pageCombo.currentIndex())


class Window(QMainWindow):
    def __init__(self):
        super(Window, self).__init__()

        self.stacked = Stacked(self)
        self.setCentralWidget(self.stacked)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec())

Here where we can set the second title? when index changed to page2

You mean this?

    def switchPage(self):
        self.stackedLayout.setCurrentIndex(self.pageCombo.currentIndex())
        self.parent().setWindowTitle(f'page {self.pageCombo.currentIndex()+1}')
1 Like

exactly, in fact I have tried this earlier. But it didn’t work for me.

But it is now!