0

I have been designing a PySide6 Application but the problem is that even if I have not added any space to the layout the layout still contains a lot of visible space.

Updated Screenshot

Debug Screenshot with widget borders as red: Updated Screenshot

Is there anyway to remove the space? Here is the code:

from PySide6 import QtCore
from PySide6.QtWidgets import (
    QMainWindow,
    QVBoxLayout,
    QFormLayout,
    QWidget,
    QApplication,
    QLabel,
    QCheckBox,
    QHBoxLayout,
    QLineEdit,
    QFileDialog,
    QPushButton
)
import os
import sys


class Styler_Py(QMainWindow):
    def __init__(self, parent=None) -> None:
        super().__init__(parent)

        # Window Setup
        self.setWindowTitle("PyStyler")

        # Layout setup        
        self.container_widget = QWidget()
        self.main_layout = QVBoxLayout()
        self.container_widget.setLayout(self.main_layout)
        self.setCentralWidget(self.container_widget)

        # Irrelevant code here

        # --- New Section ---
        self.main_layout.addSpacing(10)
        self.main_layout.addStretch()
        # --- New Section ---

        # Files
        self.files_label = QLabel("<h3>Files</h3>")  # Note for the future, the closure tag did not have forward slash and have been fixed using an answer below
        self.main_layout.addWidget(self.files_label)
        self.files_layout = QVBoxLayout()
        self.main_layout.addLayout(self.files_layout)

        # Files -> Input File
        self.input_file = FileInput()
        self.input_file_layout = QHBoxLayout()
        self.files_layout.addLayout(self.input_file_layout)
        self.input_file_label = QLabel("Input File")
        self.input_file_layout.addWidget(self.input_file_label)
        self.input_file_layout.addWidget(self.input_file)
        


class FileInput(QWidget):
    def __init__(self, start_path=os.path.expanduser("~")) -> None:
        super().__init__()
        self._main_layout = QHBoxLayout()
        self.setLayout(self._main_layout)

        # Add Text edit for File Input
        self._file_input = QLineEdit(start_path)
        self._main_layout.addWidget(self._file_input)
        self._file_input_browse = QPushButton("Browse")
        self._file_input_browse.clicked.connect(self._browse_file_dialog)
        self._main_layout.addWidget(self._file_input_browse)
        self._start_path = start_path
    
    def _browse_file_dialog(self):
        if os.path.isfile(self._file_input.text()):
            path = os.path.abspath(f"{self._file_input.text()}/..")
        if os.path.isdir(self._file_input.text()):
            path = os.path.abspath(self._file_input.text())
        else:
            path = self._start_path
        file_name = QFileDialog.getOpenFileName(
            self, "Open File", path
        )
        if len(file_name[0]) > 0:
            self._file_input.setText(file_name[0])
    
    def get_path(self):
        return self._file_input.text()


def main():
    app = QApplication(sys.argv)
    app.setStyleSheet("*{ border: 1px solid red; }")
    window = Styler_Py()
    window.show()
    app.exec()

main()

I think the problem is somewhere with my custom widget but I could not find it. I have tried adding and removing a lot of the widgets but nothing happens.

Edit A Screenshot of window when resized to be a little bigger: Screenshot but bigger window

AmaanK
  • 1,032
  • 5
  • 25
  • So your actual question appears to be: how do I [automatically resize a window to its contents](https://stackoverflow.com/q/28748966/984421)? – ekhumoro Jul 02 '21 at 06:32
  • @ekhumoro No, I know how resizing works and for me I have no problem with resizing. The real problem is with the labels those are overly expanded, even If I resize or not. – AmaanK Jul 02 '21 at 06:33
  • But where do expect the space to go if you don't resize the window smaller? The layout will just allow the widgets to grow to fill the whatever space is available. Note that the window in your 2nd screenshot is smaller than in the 1st screenshot, so, as expected, the widgets take up less space. – ekhumoro Jul 02 '21 at 15:31
  • Sorry for the outdated screenshot. I fixed one label using answer below. but the second label is still a problem. I have updated all the screenshot and added a new screenshot for big resize. – AmaanK Jul 02 '21 at 16:02
  • @xcodz-dot you added a stretch, which is a "spacer" that will expand itself if the widgets in the layout already have grown to their preferred size (and do not expand themselves). – musicamante Jul 02 '21 at 18:02
  • @xcodz-dot But what exactly is the problem? Space must be added *somewhere* when the window is resized larger, so where do you expect it to go? – ekhumoro Jul 02 '21 at 18:11
  • The screenshots provided are at their minimum size. and if i resize them bigger they they will only expand horizontally and not vertically because of adding the stretch. the problem is with the unwanted height of label named `self.input_file_label` as you can already see in the debug screenshot that it has more height than normally it should be having. – AmaanK Jul 03 '21 at 04:03
  • @xcodz-dot That label has the normal and expected height. As I said before, layouts will allow widgets to grow to fill the space avaliable to them. In this case, that space comes from the default margin of the layout contained by the `FileInput` widget. This was already pointed out to you in the answer by musicamante - but it seems you did not understand it properly. So, to spelll it out in actual code, you need to add the line following line to your example: `self._main_layout.setContentsMargins(0, 0, 0, 0)`. – ekhumoro Jul 03 '21 at 11:03
  • @ekhumoro Thank You! My bad that I did not understand what he meant to say. – AmaanK Jul 03 '21 at 12:03

1 Answers1

1

The first problem comes from the wrong tag closure, as it should be like this:

    self.files_label = QLabel("<h3>Files</h3>")

Then, that spacing is the result of two aspects: layout spacings/margins and rich text margins.

  1. layout spacings are inherited by child layouts from their parent layout (so, the input_file_layout has a default spacing inherited by the files_layout, which in turns inherits that property from the main_layout;
  2. when layout managers are installed on widgets, they use the widget's style layout margins and spacings (QStyle.PM_Layout*Margin and QStyle.PM_Layout*Spacing) unless overriden by layout.setContentsMargins() or layout.setSpacing(); this not only happens top level widgets, but for child widgets too: layouts set on children widgets do not inherit the parent layout margins or spacings, and they use the default system (or style) values; this can be overridden
  3. rich text elements normally result in bigger space required by the label's sizeHint(); unfortunately there's no easy work around for that, as also explained in the Layout Issues documentation;

In order to better understand the boundaries of each widget, you could add a simple stylesheet for testing purposes:

    app.setStyleSheet('*{ border: 1px solid black; }')

Please consider that the above will override any widget border (including buttons, for example), so use it only for debugging in order to understand how the layout works; do NOT use it for general purposes, especially if applied on the application.

musicamante
  • 41,230
  • 6
  • 33
  • 58
  • Thanks for the debugging tip, I had to sleep so could not reply. Looks like the label is taking most of the space, I have attached a screenshot – AmaanK Jul 02 '21 at 04:06
  • Looks like, two labels the `files_label` and the `input_file_label` are expanded for no reason. I have not used a single stylesheet or spacing policy in the code. – AmaanK Jul 02 '21 at 04:11
  • 1
    @xcodz-dot fix your tag closure: it should be `

    Files

    `
    – musicamante Jul 02 '21 at 04:22
  • Ok the label problem from first label is gone but exists for the second label – AmaanK Jul 02 '21 at 06:31