Что можно выбрать для хранения виджетов в окне?

У меня появилась необходимость сделать две страницы. Каждая страница должна иметь цветной фон. В эти страницы я хочу поместить разные виджеты(надписи, кнопки и другое; наполнение первой страницы будет отличаться от наполнения второй). При нажатии на кнопку btn1 мне бы хотелось открывать первую страницу, при нажатии на кнопку btn2 - вторую:

введите сюда описание изображения

Я не знаю, какой виджет лучше всего взять, чтобы осуществить такой 'контейнер'. Пожалуйста, подскажите, как его можно сделать?

from PyQt5 import QtCore, QtGui, QtWidgets

class MyWindow(QtWidgets.QWidget):
    def __init__(self, *args, **kwargs):
        super(MyWindow, self).__init__(*args, **kwargs)

        btn1 = QtWidgets.QPushButton('Button1')   # Кнопка, которая должна открывать страницу 1
        btn2 = QtWidgets.QPushButton('Button2')   # Кнопка, которая должна открывать страницу 2
        box1 = QtWidgets.QGridLayout(self)   # Основной контейнер
        box1.addWidget(btn1, 1, 0)
        box1.addWidget(btn2, 1, 1)

        label1_1 = QtWidgets.QLabel('Страница 1', self)     # |
        label2_1 = QtWidgets.QLabel('Содержимое 1', self)   # |   Страница 1
        page_btn1 =QtWidgets.QPushButton('1')               # |

        #label1_2 = QtWidgets.QLabel('Страница 2', self)     # |
        #label2_2 = QtWidgets.QLabel('Содержимое 2', self)   # |   Страница 2
        #page_btn2 =QtWidgets.QPushButton('2')               # |

        box2 = QtWidgets.QVBoxLayout()   # Контенер для виджетов страницы 1
        box2.addWidget(label1_1)
        box2.addWidget(label2_1)
        box2.addWidget(page_btn1)

        box1.addLayout(box2, 0, 0, 1, 2, alignment = QtCore.Qt.AlignCenter)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

Ответы (2 шт):

Автор решения: gil9red

Попробуйте QStackedWidget.

Этот виджет может размещать на себе разные виджеты, но показывать только один в данный момент:

from PyQt5 import QtCore, QtGui, QtWidgets


class MyWindow(QtWidgets.QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.stacked_widget = QtWidgets.QStackedWidget()
        self.stacked_widget.addWidget(self.build_page_1())
        self.stacked_widget.addWidget(self.build_page_2())

        btn1 = QtWidgets.QPushButton('Button1')  # Кнопка, которая должна открывать страницу 1
        btn1.clicked.connect(lambda: self.stacked_widget.setCurrentIndex(0))

        btn2 = QtWidgets.QPushButton('Button2')  # Кнопка, которая должна открывать страницу 2
        btn2.clicked.connect(lambda: self.stacked_widget.setCurrentIndex(1))

        main_layout = QtWidgets.QGridLayout()   # Основной контейнер
        main_layout.addWidget(self.stacked_widget, 0, 0, 1, 2, alignment=QtCore.Qt.AlignCenter)
        main_layout.addWidget(btn1, 1, 0)
        main_layout.addWidget(btn2, 1, 1)

        self.setLayout(main_layout)

    def build_page_1(self):
        self.label1_1 = QtWidgets.QLabel('Страница 1', self)     # |
        self.label2_1 = QtWidgets.QLabel('Содержимое 1', self)   # |   Страница 1
        self.page_btn1 =QtWidgets.QPushButton('1')               # |

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.label1_1)
        layout.addWidget(self.label2_1)
        layout.addWidget(self.page_btn1)

        widget = QtWidgets.QWidget()
        widget.setLayout(layout)

        return widget

    def build_page_2(self):
        self.label1_2 = QtWidgets.QLabel('Страница 2', self)  # |
        self.label2_2 = QtWidgets.QLabel('Содержимое 2', self)  # |   Страница 2
        self.page_btn2 = QtWidgets.QPushButton('2')  # |

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.label1_2)
        layout.addWidget(self.label2_2)
        layout.addWidget(self.page_btn2)

        widget = QtWidgets.QWidget()
        widget.setLayout(layout)

        return widget


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())
→ Ссылка
Автор решения: S. Nick

Я увидел вашу задачу так:

from PyQt5 import QtCore, QtGui, QtWidgets


class Window1(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Window1, self).__init__(parent)
        self.setFixedSize(300, 200)
        self.setObjectName('window1')
        self.setStyleSheet('''
            QWidget {
                background-color: #f77; 
                font-weight: bold;
                font-size: 15px;
            }
        ''')

        self.labelPage = QtWidgets.QLabel('Страница 1', self, alignment=QtCore.Qt.AlignCenter)
        self.labelContent = QtWidgets.QLabel('Содержимое 1', self, alignment=QtCore.Qt.AlignCenter) 
        self.page_btn =QtWidgets.QPushButton('page_btn 1')                  

        self.box2 = QtWidgets.QVBoxLayout(self)              
        self.box2.addWidget(self.labelPage)
        self.box2.addWidget(self.labelContent)
        self.box2.addWidget(self.page_btn)     


class Window2(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Window2, self).__init__(parent)
        self.setFixedSize(300, 200)
        self.setObjectName('window2')
        self.setStyleSheet('''
            QWidget {
                background-color: #777; 
                font-weight: bold;
                font-size: 15px;
            }
        ''')

        self.labelPage = QtWidgets.QLabel('Страница 2', self, alignment=QtCore.Qt.AlignCenter)
        self.labelContent = QtWidgets.QLabel('Содержимое 2', self, alignment=QtCore.Qt.AlignCenter) 
        self.page_btn =QtWidgets.QPushButton('page_btn 2')                  

        self.box2 = QtWidgets.QVBoxLayout(self) 
        self.box2.addWidget(self.labelPage)
        self.box2.addWidget(self.labelContent)
        self.box2.addWidget(self.page_btn)          


class MyWindow(QtWidgets.QWidget):
    def __init__(self, *args, **kwargs):
        super(MyWindow, self).__init__(*args, **kwargs)          # MyWindow

        self.btn1 = QtWidgets.QPushButton('Button1')   # Кнопка, которая должна открывать страницу 1
        self.btn1.clicked.connect(self.onClickedBtn1)
        self.btn1.setEnabled(False)
        self.btn2 = QtWidgets.QPushButton('Button2')   # Кнопка, которая должна открывать страницу 2
        self.btn2.clicked.connect(self.onClickedBtn2)

        self.window1 = Window1() 
        self.window2 = Window2()

        self.box1 = QtWidgets.QGridLayout(self)        # Основной контейнер
#        box1.addLayout(box2, 0, 0, 1, 2, alignment=QtCore.Qt.AlignCenter)
        self.box1.addWidget(self.window1, 0, 0, 1, 2, alignment=QtCore.Qt.AlignCenter)
        self.box1.addWidget(self.btn1, 1, 0)
        self.box1.addWidget(self.btn2, 1, 1)        

    def onClickedBtn1(self):
        self.window2.hide()
        self.box1.addWidget(self.window1, 0, 0, 1, 2, alignment=QtCore.Qt.AlignCenter)
        self.window1.show()
        self.btn1.setEnabled(False)
        self.btn2.setEnabled(True) 

    def onClickedBtn2(self):
        self.window1.hide()
        self.box1.addWidget(self.window2, 0, 0, 1, 2, alignment=QtCore.Qt.AlignCenter)
        self.window2.show()
        self.btn2.setEnabled(False) 
        self.btn1.setEnabled(True)        


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения


Update

В вашем варианте нельзя задать фон для всех элементов, и появляются бесцветные полосы между элементами. Мне следует задать новый вопрос?

Не надо задавать вопросы по этому поводу. Есть таблицы стилей, где можно сделать все что вы хотите.

from PyQt5 import QtCore, QtGui, QtWidgets


class Window1(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Window1, self).__init__(parent)

        self.window = QtWidgets.QWidget()
        self.window.setObjectName('window1')
        self.window.setMinimumSize(300, 200)

        self.labelPage = QtWidgets.QLabel('Страница 1', self, alignment=QtCore.Qt.AlignCenter)
        self.labelContent = QtWidgets.QLabel('Содержимое 1', self, alignment=QtCore.Qt.AlignCenter) 
        self.page_btn =QtWidgets.QPushButton('page_btn 1')                  

        self.box2 = QtWidgets.QVBoxLayout(self.window)              
        self.box2.addWidget(self.labelPage)
        self.box2.addWidget(self.labelContent)
        self.box2.addWidget(self.page_btn)   

        box = QtWidgets.QHBoxLayout(self)  
        box.addWidget(self.window)


class Window2(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Window2, self).__init__(parent)
        self.window = QtWidgets.QWidget()
        self.window.setObjectName('window2')
        self.window.setMinimumSize(300, 200)
        self.labelPage = QtWidgets.QLabel('Страница 2', self, alignment=QtCore.Qt.AlignCenter)
        self.labelContent = QtWidgets.QLabel('Содержимое 2', self, alignment=QtCore.Qt.AlignCenter) 
        self.page_btn =QtWidgets.QPushButton('page_btn 2')                  
        self.box2 = QtWidgets.QVBoxLayout(self.window)              
        self.box2.addWidget(self.labelPage)
        self.box2.addWidget(self.labelContent)
        self.box2.addWidget(self.page_btn)   
        box = QtWidgets.QHBoxLayout(self)  
        box.addWidget(self.window)        


class MyWindow(QtWidgets.QWidget):
    def __init__(self, *args, **kwargs):
        super(MyWindow, self).__init__(*args, **kwargs)          

        self.btn1 = QtWidgets.QPushButton('Button1')   # Кнопка, которая должна открывать страницу 1
        self.btn1.clicked.connect(self.onClickedBtn1)
        self.btn1.setEnabled(False)
        self.btn2 = QtWidgets.QPushButton('Button2')   # Кнопка, которая должна открывать страницу 2
        self.btn2.clicked.connect(self.onClickedBtn2)

        self.window1 = Window1() 
        self.window2 = Window2()

        self.box1 = QtWidgets.QGridLayout(self)        # Основной контейнер
        self.box1.addWidget(self.window1, 0, 0, 1, 2, alignment=QtCore.Qt.AlignCenter)
        self.box1.addWidget(self.btn1, 1, 0)
        self.box1.addWidget(self.btn2, 1, 1)        

    def onClickedBtn1(self):
        self.window2.hide()
        self.box1.addWidget(self.window1, 0, 0, 1, 2, alignment=QtCore.Qt.AlignCenter)
        self.window1.show()
        self.btn1.setEnabled(False)
        self.btn2.setEnabled(True) 
        self.window1.setGeometry(0, 0, self.width(), self.height()-50)
        self.update()

    def onClickedBtn2(self):
        self.window1.hide()
        self.box1.addWidget(self.window2, 0, 0, 1, 2, alignment=QtCore.Qt.AlignCenter)
        self.window2.show()
        self.btn2.setEnabled(False) 
        self.btn1.setEnabled(True)        
        self.window2.setGeometry(0, 0, self.width(), self.height()-50)
        self.update()

    def resizeEvent(self, event):
        super(MyWindow, self).resizeEvent(event)
        self.window1.setGeometry(0, 0, self.width(), self.height()-50)
        self.window2.setGeometry(0, 0, self.width(), self.height()-50)
        self.update()


qss ='''
QWidget {
    background-color: #999; 
    font-weight: bold;
    font-size: 15px;
}
#window1{
    background-color: #f77; 
}
#window1 QLabel{
    background-color: #f55; 
}
#window1 QPushButton {
    background-color: #f33; 
}

#window2{
    background-color: #0f0; 
}
#window2 QLabel{
    background-color: #ff5; 
}
#window2 QPushButton {
    background-color: #afa; 
}
'''

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    app.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold))
    app.setStyleSheet(qss)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка