I am designing a ui
in qt-desginer
. I have to create a UI which has a side menu bar with buttons and whichever button is pressed, its appropriate data will be shown on right side.
To design this, I have I have placed two QFrame
in horizontal layout
on central widget. I have reduced the width of left side QFrame
named side_menu_bar
and thus it has become the side menu bar. On the right side QFrame
named content_area
, I have placed a stackedWidget
with multiple pages.
Now whatever data I want to show on stackedWidget
has to cover the complete area of content_area
and thus I have used a vertical layout
on stackedWidget
. On the page_2
of stackedWidget
, I have placed a tablewidget
. This page_2
will be shown if a user clicks pushButton
on side menu bar.
Below is the python code of the UI file:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'home2.ui'
#
# Created by: PyQt5 UI code generator 5.15.0
#
# 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, QtGui, QtWidgets
class Ui_home_window(object):
def setupUi(self, home_window):
home_window.setObjectName("home_window")
home_window.resize(1216, 613)
self.centralwidget = QtWidgets.QWidget(home_window)
self.centralwidget.setObjectName("centralwidget")
self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
self.layoutWidget.setGeometry(QtCore.QRect(2, 0, 1211, 611))
self.layoutWidget.setObjectName("layoutWidget")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.layoutWidget)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.side_menu_bar = QtWidgets.QFrame(self.layoutWidget)
self.side_menu_bar.setMinimumSize(QtCore.QSize(0, 0))
self.side_menu_bar.setMaximumSize(QtCore.QSize(120, 16777215))
self.side_menu_bar.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.side_menu_bar.setFrameShadow(QtWidgets.QFrame.Raised)
self.side_menu_bar.setObjectName("side_menu_bar")
self.pushButton = QtWidgets.QPushButton(self.side_menu_bar)
self.pushButton.setGeometry(QtCore.QRect(20, 100, 75, 23))
self.pushButton.setObjectName("pushButton")
self.horizontalLayout_2.addWidget(self.side_menu_bar)
self.content_area = QtWidgets.QFrame(self.layoutWidget)
self.content_area.setStyleSheet("background-color: rgb(170, 255, 0);")
self.content_area.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.content_area.setFrameShadow(QtWidgets.QFrame.Raised)
self.content_area.setObjectName("content_area")
self.verticalLayoutWidget = QtWidgets.QWidget(self.content_area)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(9, 9, 1071, 591))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.stackedWidget = QtWidgets.QStackedWidget(self.verticalLayoutWidget)
self.stackedWidget.setObjectName("stackedWidget")
self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
self.stackedWidget.addWidget(self.page)
self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2")
self.tableWidget = QtWidgets.QTableWidget(self.page_2)
self.tableWidget.setGeometry(QtCore.QRect(0, 0, 1071, 591))
self.tableWidget.setRowCount(50)
self.tableWidget.setColumnCount(50)
self.tableWidget.setObjectName("tableWidget")
self.stackedWidget.addWidget(self.page_2)
self.verticalLayout.addWidget(self.stackedWidget)
self.horizontalLayout_2.addWidget(self.content_area)
home_window.setCentralWidget(self.centralwidget)
self.retranslateUi(home_window)
QtCore.QMetaObject.connectSlotsByName(home_window)
def retranslateUi(self, home_window):
_translate = QtCore.QCoreApplication.translate
home_window.setWindowTitle(_translate("home_window", "MainWindow"))
self.pushButton.setText(_translate("home_window", "PushButton"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
home_window = QtWidgets.QMainWindow()
ui = Ui_home_window()
ui.setupUi(home_window)
home_window.show()
sys.exit(app.exec_())
and below is how I am using it in app.py
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from src.home2_ui import Ui_home_window
class HomeWindow(QMainWindow, Ui_home_window):
def __init__(self):
QMainWindow.__init__(self)
self.home_ui = Ui_home_window()
self.home_ui.setupUi(self)
self.showMaximized()
layout = self.home_ui.horizontalLayout_2
self.home_ui.centralwidget.setLayout(layout)
self.home_ui.pushButton.clicked.connect(self.show_page2)
def show_page2(self):
layout2 = self.home_ui.verticalLayout
layout2.addWidget(self.home_ui.stackedWidget)
self.home_ui.content_area.setLayout(layout2)
app = QApplication(sys.argv)
main_window = HomeWindow()
main_window.show()
sys.exit(app.exec_())
Now as per my understanding, I want to show my application full screen and want to fit the complete area of the window. So for that I have attached the horizontal layout
to central widget
:
layout = self.home_ui.horizontalLayout_2
self.home_ui.centralwidget.setLayout(layout)
Now in order to make table widget cover the complete area of stacked widget I have used below code on button press event:
layout2 = self.home_ui.verticalLayout
layout2.addWidget(self.home_ui.stackedWidget)
self.home_ui.content_area.setLayout(layout2)
As per my understanding whatever widget we want to show in stacked widget has to cover the complete area of stacked widget and thus I have attached stacked widget to vertical layout and then I have set the layout of content area to layout2 (which is vertical layout). Now by doing this, if I click on the button to show table widget, nothing is getting shown:
Here I have a question, when I click on pushbutton to show table widget, table widget is not shown but instead a blank window is shown which is also covering the side menu bar.?
If I replace the above code to:
layout2 = self.home_ui.verticalLayout
layout2.addWidget(self.home_ui.tableWidget)
self.home_ui.content_area.setLayout(layout2)
so In this case I have added table widget to vertical layout instead of stacked widget. Below is the output:
It does shows table but only on half screen. Also it has removed the side menu bar too.
I am not able to fully understand how to use the layout
when using stacked widgets
. Can anyone please guide me on how to do this. Please help. Thanks
Here is the link to download the home2.ui
file
Update:
I have finally been able to resolve this. I have used horizontal layout which is acting as a base layout and it has two childrens content area
and side menu bar
. Both content area
and side menu bar
have vertical layout. In side menu bar
I can add as many as I want and it will be auto aligned due to vertical layout. In content area
I have added stacked widget which is again a child of vertical layout. In page 2 of stacked widget, I had to add another vertical layout and then added table widget. Now it showing perfectly.
Below is all the code:
UI CODE:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'home5.ui'
#
# Created by: PyQt5 UI code generator 5.15.0
#
# 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, QtGui, QtWidgets
class Ui_home_window(object):
def setupUi(self, home_window):
home_window.setObjectName("home_window")
home_window.resize(1196, 573)
self.centralwidget = QtWidgets.QWidget(home_window)
self.centralwidget.setObjectName("centralwidget")
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(10, 10, 1181, 561))
self.widget.setObjectName("widget")
self.base_h_layout = QtWidgets.QHBoxLayout(self.widget)
self.base_h_layout.setContentsMargins(0, 0, 0, 0)
self.base_h_layout.setSpacing(0)
self.base_h_layout.setObjectName("base_h_layout")
self.side_menu_bar = QtWidgets.QFrame(self.widget)
self.side_menu_bar.setMaximumSize(QtCore.QSize(120, 16777215))
self.side_menu_bar.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.side_menu_bar.setFrameShadow(QtWidgets.QFrame.Raised)
self.side_menu_bar.setObjectName("side_menu_bar")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.side_menu_bar)
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_2.setSpacing(0)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.menu_bar_v_layout = QtWidgets.QVBoxLayout()
self.menu_bar_v_layout.setContentsMargins(10, 10, 10, 10)
self.menu_bar_v_layout.setSpacing(10)
self.menu_bar_v_layout.setObjectName("menu_bar_v_layout")
self.pushButton = QtWidgets.QPushButton(self.side_menu_bar)
self.pushButton.setObjectName("pushButton")
self.menu_bar_v_layout.addWidget(self.pushButton)
self.verticalLayout_2.addLayout(self.menu_bar_v_layout)
self.base_h_layout.addWidget(self.side_menu_bar)
self.content_area = QtWidgets.QFrame(self.widget)
self.content_area.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.content_area.setFrameShadow(QtWidgets.QFrame.Raised)
self.content_area.setObjectName("content_area")
self.verticalLayout = QtWidgets.QVBoxLayout(self.content_area)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setSpacing(0)
self.verticalLayout.setObjectName("verticalLayout")
self.content_area_v_layout = QtWidgets.QVBoxLayout()
self.content_area_v_layout.setSpacing(0)
self.content_area_v_layout.setObjectName("content_area_v_layout")
self.stackedWidget = QtWidgets.QStackedWidget(self.content_area)
self.stackedWidget.setObjectName("stackedWidget")
self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
self.stackedWidget.addWidget(self.page)
self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.page_2)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.table_v_layout = QtWidgets.QVBoxLayout()
self.table_v_layout.setSpacing(0)
self.table_v_layout.setObjectName("table_v_layout")
self.tableWidget = QtWidgets.QTableWidget(self.page_2)
self.tableWidget.setRowCount(50)
self.tableWidget.setColumnCount(50)
self.tableWidget.setObjectName("tableWidget")
self.table_v_layout.addWidget(self.tableWidget)
self.verticalLayout_4.addLayout(self.table_v_layout)
self.stackedWidget.addWidget(self.page_2)
self.content_area_v_layout.addWidget(self.stackedWidget)
self.verticalLayout.addLayout(self.content_area_v_layout)
self.base_h_layout.addWidget(self.content_area)
home_window.setCentralWidget(self.centralwidget)
self.retranslateUi(home_window)
QtCore.QMetaObject.connectSlotsByName(home_window)
def retranslateUi(self, home_window):
_translate = QtCore.QCoreApplication.translate
home_window.setWindowTitle(_translate("home_window", "MainWindow"))
self.pushButton.setText(_translate("home_window", "PushButton"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
home_window = QtWidgets.QMainWindow()
ui = Ui_home_window()
ui.setupUi(home_window)
home_window.show()
sys.exit(app.exec_())
app.py:
class HomeWindow(QMainWindow, Ui_home_window):
def __init__(self):
QMainWindow.__init__(self)
self.home_ui = Ui_home_window()
self.home_ui.setupUi(self)
self.showMaximized()
base_layout = self.home_ui.base_h_layout
self.home_ui.centralwidget.setLayout(base_layout)
side_menu_v_layout = self.home_ui.menu_bar_v_layout
self.home_ui.side_menu_bar.setLayout(side_menu_v_layout)
content_v_layout = self.home_ui.content_area_v_layout
self.home_ui.content_area.setLayout(content_v_layout)
table_layout = self.home_ui.table_v_layout
self.home_ui.page_2.setLayout(table_layout)
self.home_ui.pushButton.clicked.connect(self.show_page2)
def show_page2(self):
self.home_ui.stackedWidget.setCurrentWidget(self.home_ui.page_2)
and this is how the qt-designer
object inspector looks like:
Thanks to @allec and @musicamante.
The
side_menu_bar
does not appear because it has no layout manager to determine a proper size. Even though you added a child button directly to the frame, it will not resize accordingly unless you explicitly tell it to. You have a lot of extra placeholder QWidgets, particularlylayoutWidget
,verticalLayoutWidget
, andpage_2
that are making this design more complicated than necessary. Any kind of widget can be added directly to the layout or stacked widget. The two QFrames should each have a layout only containing the child widgets.There is no need to further set layouts to widgets in
HomeWindow
, you can switch to the other page withQStackedWidget.setCurrentIndex()
.Before pressing button:
After pressing button: