Issue with padding/placement PyQT6 Python
-
wrote on 3 Oct 2024, 20:07 last edited by
I'm trying to make a menu with a sidebar for different widgets/frames. The issue is the items inside the frame it's on in this case my dashboard frame, have padding? For some reason I can't get it to where it goes to the top and it lets me manually change it how I want. Here is the code
# code block import sys from PyQt6.QtWidgets import ( QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton, QStackedWidget, QLabel, QHBoxLayout, QGridLayout ) from PyQt6.QtCore import Qt from PyQt6.QtGui import QIcon, QFont, QFontDatabase class MainWindow(QMainWindow): def __init__(self): super().__init__() # Application Configuration self.resize(800, 600) self.setWindowIcon(QIcon("./Images/clown.ico")) self.setWindowTitle("Recalcitrant V1.0.0") # Create a central widget and main layout self.centralWidget = QWidget() self.setCentralWidget(self.centralWidget) mainLayout = QHBoxLayout(self.centralWidget) # Use QHBoxLayout for side-by-side self.sidebarFrame = self.createSidebarFrame() self.stacked_widget = QStackedWidget() # Create frames self.dashboardFrame = self.createDashboardFrame() self.frame2 = self.create_frame("This is Frame 2") self.frame3 = self.create_frame("This is Frame 3") # Add frames to the stacked widget self.stacked_widget.addWidget(self.dashboardFrame) self.stacked_widget.addWidget(self.frame2) self.stacked_widget.addWidget(self.frame3) # Add sidebar and stacked widget to the main layout mainLayout.addWidget(self.sidebarFrame) # Add sidebar first mainLayout.addWidget(self.stacked_widget) # Then the stacked widget # Set the fixed width for the sidebar self.sidebarFrame.setFixedWidth(150) def createSidebarFrame(self): sidebarWidget = QWidget() sidebarWidget.setObjectName("sidebar") sidebar = QVBoxLayout() sidebar.setAlignment(Qt.AlignmentFlag.AlignTop) # Align sidebar to the top sidebarWidget.setStyleSheet(""" QWidget#sidebar { background-color: #22222E; border-radius: 10px; } QPushButton#button { background-color: #22222E; border: 2px solid #ffffff; border-radius: 10px; padding: 5px; } QPushButton#button:hover { background-color: #393A5A; } QLabel#sidebarLabels { text-align: center; color: white; } """) sidebarWidget.setLayout(sidebar) # Dashboard self.modulesText = QLabel("<div style='text-align: center;'>test</div>") self.modulesText.setObjectName("sidebarLabels") sidebar.addWidget(self.modulesText) self.test = QPushButton("DASHBOARD") self.test.setMaximumWidth(150) self.test.setMinimumWidth(100) self.test.setObjectName("button") self.test.clicked.connect(lambda: self.switch_frame("dashboard")) sidebar.addWidget(self.test) # test self.test = QLabel("<div style='text-align: center;'>test</div>") self.test.setObjectName("sidebarLabels") sidebar.addWidget(self.test) self.test = QPushButton("test") self.test.setMaximumWidth(150) self.test.setMinimumWidth(100) self.test.setObjectName("button") self.test.clicked.connect(lambda: self.switch_frame(1)) sidebar.addWidget(self.test) # test self.test = QLabel("<div style='text-align: center;'>test</div>") self.test.setObjectName("sidebarLabels") sidebar.addWidget(self.test) self.test = QPushButton("test") self.test.setMaximumWidth(150) self.test.setMinimumWidth(100) self.test.setObjectName("button") self.test.clicked.connect(lambda: self.switch_frame(2)) sidebar.addWidget(self.test) sidebarWidget.setContentsMargins(0, 5, 0, 5) return sidebarWidget # Return the sidebar widget, not the layout def createDashboardFrame(self): frame = QWidget() frame.setStyleSheet(""" QLabel#label { border: 2px solid #ffffff; border-radius: 10px; padding: 0px; } """) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) frame.setLayout(layout) hbox = QHBoxLayout() layout.addLayout(hbox) test = QLabel("<div style='text-align: center;'>test test</div>") test.setObjectName("label") hbox.addWidget(test) test = QLabel("<div style='text-align: center;'>test test</div>") test.setObjectName("label") hbox.addWidget(test) test = QLabel("<div style='text-align: center;'>test test test</div>") test.setObjectName("label") hbox.addWidget(test) vbox = QVBoxLayout() layout.addLayout(vbox) button = QPushButton("test") vbox.addWidget(button) button = QPushButton("test") vbox.addWidget(button) button = QPushButton("test") vbox.addWidget(button) return frame def create_frame(self, text): """Helper function to create a frame with a label.""" frame = QWidget() layout = QVBoxLayout() label = QLabel(text) layout.addWidget(label) frame.setLayout(layout) return frame def switch_frame(self, index): """Switch to the specified frame.""" if index == "dashboard": self.stacked_widget.setCurrentIndex(0) self.test.setStyleSheet("background-color: #393A5A;") self.test.setStyleSheet("") self.test.setStyleSheet("") elif index == 1: self.stacked_widget.setCurrentIndex(index) self.test.setStyleSheet("") self.test.setStyleSheet("background-color: #393A5A;") self.test.setStyleSheet("") elif index == 2: self.stacked_widget.setCurrentIndex(index) self.test.setStyleSheet("") self.test.setStyleSheet("") self.test.setStyleSheet("background-color: #393A5A;") if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() from styles import style app.setStyleSheet(style) window.show() sys.exit(app.exec())
The code's variable names and text was changed for privacy.
Here is the output
You can see that the border is pushed out even though there padding is set to 0. I'm insanely new to pyqt6 so I'm still learning but all help is appreciated. Thank you. -
Hi and welcome to devnet,
You need to also modify the layouts' content margins as well as spacing.
-
Hi and welcome to devnet,
You need to also modify the layouts' content margins as well as spacing.
wrote on 5 Oct 2024, 02:05 last edited by@SGaist I already set the content margins. I tried doing padding and it didn't make a difference, not sure if I did it on the wrong spot. Here is my new code.
def createDashboardFrame(self): frame = QWidget() frame.setContentsMargins(0, 0, 0, 0) frame.setStyleSheet(""" QLabel#label { border: 2px solid #ffffff; border-radius: 10px; padding: 0px; } """) layout = QVBoxLayout() layout.setSpacing(0) frame.setLayout(layout) hbox = QHBoxLayout() layout.addLayout(hbox) test = QLabel("<div style='text-align: center;'>test test</div>") test.setObjectName("label") hbox.addWidget(test) test = QLabel("<div style='text-align: center;'>test test</div>") test.setObjectName("label") hbox.addWidget(test) test = QLabel("<div style='text-align: center;'>test test test</div>") test.setObjectName("label") hbox.addWidget(test) vbox = QVBoxLayout() layout.addLayout(vbox) button = QPushButton("test") vbox.addWidget(button) button = QPushButton("test") vbox.addWidget(button) button = QPushButton("test") vbox.addWidget(button) return frame
As you can see I have
frame.setContentsMargins(0, 0, 0, 0)
Which was already in the code. I now have
layout.setSpacing(0)
This is what it looks like now. Which from what I can see is it just removed all the gaps
-
Something like the following ?
# code block import sys from PyQt6.QtWidgets import ( QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton, QStackedWidget, QLabel, QHBoxLayout, QGridLayout ) from PyQt6.QtCore import Qt from PyQt6.QtGui import QIcon, QFont, QFontDatabase class MainWindow(QMainWindow): def __init__(self): super().__init__() # Application Configuration self.resize(800, 600) self.setWindowIcon(QIcon("./Images/clown.ico")) self.setWindowTitle("Recalcitrant V1.0.0") # Create a central widget and main layout self.centralWidget = QWidget() self.setCentralWidget(self.centralWidget) mainLayout = QHBoxLayout(self.centralWidget) # Use QHBoxLayout for side-by-side self.sidebarFrame = self.createSidebarFrame() self.stacked_widget = QStackedWidget() # Create frames self.dashboardFrame = self.createDashboardFrame() self.frame2 = self.create_frame("This is Frame 2") self.frame3 = self.create_frame("This is Frame 3") # Add frames to the stacked widget self.stacked_widget.addWidget(self.dashboardFrame) self.stacked_widget.addWidget(self.frame2) self.stacked_widget.addWidget(self.frame3) # Add sidebar and stacked widget to the main layout mainLayout.addWidget(self.sidebarFrame) # Add sidebar first mainLayout.addWidget(self.stacked_widget) # Then the stacked widget mainLayout.setContentsMargins(0, 0, 0, 0) mainLayout.setSpacing(0) # Set the fixed width for the sidebar self.sidebarFrame.setFixedWidth(150) def createSidebarFrame(self): sidebarWidget = QWidget() sidebarWidget.setObjectName("sidebar") sidebar = QVBoxLayout() sidebar.setAlignment(Qt.AlignmentFlag.AlignTop) # Align sidebar to the top sidebarWidget.setStyleSheet(""" QWidget#sidebar { background-color: #22222E; border-radius: 10px; } QPushButton#button { background-color: #22222E; border: 2px solid #ffffff; border-radius: 10px; padding: 5px; } QPushButton#button:hover { background-color: #393A5A; } QLabel#sidebarLabels { text-align: center; color: white; } """) sidebarWidget.setLayout(sidebar) # Dashboard self.modulesText = QLabel("<div style='text-align: center;'>test</div>") self.modulesText.setObjectName("sidebarLabels") sidebar.addWidget(self.modulesText) self.test = QPushButton("DASHBOARD") self.test.setMaximumWidth(150) self.test.setMinimumWidth(100) self.test.setObjectName("button") self.test.clicked.connect(lambda: self.switch_frame("dashboard")) sidebar.addWidget(self.test) # test self.test = QLabel("<div style='text-align: center;'>test</div>") self.test.setObjectName("sidebarLabels") sidebar.addWidget(self.test) self.test = QPushButton("test") self.test.setMaximumWidth(150) self.test.setMinimumWidth(100) self.test.setObjectName("button") self.test.clicked.connect(lambda: self.switch_frame(1)) sidebar.addWidget(self.test) # test self.test = QLabel("<div style='text-align: center;'>test</div>") self.test.setObjectName("sidebarLabels") sidebar.addWidget(self.test) self.test = QPushButton("test") self.test.setMaximumWidth(150) self.test.setMinimumWidth(100) self.test.setObjectName("button") self.test.clicked.connect(lambda: self.switch_frame(2)) sidebar.addWidget(self.test) sidebar.setContentsMargins(0, 5, 0, 5) #sidebar.setSpacing(0) sidebarWidget.setContentsMargins(0, 5, 0, 5) return sidebarWidget # Return the sidebar widget, not the layout def createDashboardFrame(self): frame = QWidget() frame.setStyleSheet(""" QLabel#label { border: 2px solid #ffffff; border-radius: 10px; padding: 0px; } """) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) frame.setLayout(layout) hbox = QHBoxLayout() layout.addLayout(hbox) test = QLabel("<div style='text-align: center;'>test test</div>") test.setObjectName("label") hbox.addWidget(test) test = QLabel("<div style='text-align: center;'>test test</div>") test.setObjectName("label") hbox.addWidget(test) test = QLabel("<div style='text-align: center;'>test test test</div>") test.setObjectName("label") hbox.addWidget(test) vbox = QVBoxLayout() layout.addLayout(vbox) button = QPushButton("test") vbox.addWidget(button) button = QPushButton("test") vbox.addWidget(button) button = QPushButton("test") vbox.addWidget(button) return frame def create_frame(self, text): """Helper function to create a frame with a label.""" frame = QWidget() layout = QVBoxLayout() label = QLabel(text) layout.addWidget(label) frame.setLayout(layout) return frame def switch_frame(self, index): """Switch to the specified frame.""" if index == "dashboard": self.stacked_widget.setCurrentIndex(0) self.test.setStyleSheet("background-color: #393A5A;") self.test.setStyleSheet("") self.test.setStyleSheet("") elif index == 1: self.stacked_widget.setCurrentIndex(index) self.test.setStyleSheet("") self.test.setStyleSheet("background-color: #393A5A;") self.test.setStyleSheet("") elif index == 2: self.stacked_widget.setCurrentIndex(index) self.test.setStyleSheet("") self.test.setStyleSheet("") self.test.setStyleSheet("background-color: #393A5A;") if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())
1/4