Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Managing the Size of Layouts and Widgets within them...
Forum Updated to NodeBB v4.3 + New Features

Managing the Size of Layouts and Widgets within them...

Scheduled Pinned Locked Moved Solved Qt for Python
4 Posts 3 Posters 27.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    BD4L
    wrote on last edited by
    #1

    Hi friends,

    I'm working on understanding how to get my application to look the way I want it to with the layouts functionality using PySide2. I have 3 specific questions/issues I'm looking for some help with.

    1. Is there a way to make it so that when a selection is made between two radio buttons one of two Widgets appears in the same place (in this case a QLineEdit and a QComboBox widget).

    2. Is there a way to control the spacing of widgets other than using padding? With my radio buttons I'm using a horizontal layout within a vertical layout to put them side by side but there are only two of them and I don't like how far apart they are so I'd like to center them within the layout with a fixed padding size between the two widgets. Is that possible?

    3. The application I'm building will be run in full screen mode when it's all built. Is there a way to fix the size of a column in a horizontal layout (or a row in a vertical layout) so it always takes up a specific percentage of the total window size. Currently I'm using layouts within layouts to structure the document. For example with the code below if I want VertLay (which is the layout used as the second column in HorizLay) to always be 1/3 of the total screen is there an easy way to do that?

    Thanks in advance for any advice you can give me. The code I'm working with is below.

    from PySide2.QtCore import Qt
    from PySide2.QtWidgets import QApplication, QWidget, QVBoxLayout
    from PySide2.QtWidgets import QLineEdit, QListWidget, QLabel
    from PySide2.QtWidgets import QRadioButton, QButtonGroup
    from PySide2.QtWidgets import QComboBox, QHBoxLayout
    
    
    from sys import exit as sysExit
    
    class Widget(QWidget):
        def __init__(self):
            QWidget.__init__(self)
    
            self.radiobutton1 = QRadioButton("New")
            self.radiobutton2 = QRadioButton("Load")
    
            self.label1 = QLabel("Name")
            self.newvalue = QLineEdit()
            self.selectvalue = QComboBox()
    
            self.datalist = QListWidget()
    
            self.radiobuttons = QButtonGroup()
            self.radiobuttons.addButton(self.radiobutton1)
            self.radiobuttons.addButton(self.radiobutton2)
    
            RadioLay = QHBoxLayout()
            RadioLay.addWidget(self.radiobutton1)
            RadioLay.addWidget(self.radiobutton2)
    
            VertLay = QVBoxLayout()
            VertLay.addLayout(RadioLay)
            VertLay.addWidget(self.label1)
            VertLay.addWidget(self.newvalue)
    
            HorizLay = QHBoxLayout()
            HorizLay.addWidget(self.datalist)
            HorizLay.addLayout(VertLay)
    
            self.setLayout(HorizLay)
    
    if __name__ == "__main__":
        MainEventHandler = QApplication([])
    
        application = Widget()
        application.show()
        
        sysExit(MainEventHandler.exec_())
    
    1 Reply Last reply
    0
    • B BD4L

      @alom @Denni-0

      Hey friends thanks for the quick responses. These are really helpful. The toggles work great for displaying only the fields I want to show, and I really like the vertical spacer that alom used but I'm wondering if there's a way to make it so users can't move the spacer to adjust the size of the column.

      The one thing that still doesn't seem to be working is centering the radio buttons in their layout area. When the view is stretched the radio buttons are shifted left of center with too much spacing between them:

      Layout2.PNG

      When the view is more compact the New button is left justified instead of centered and there's still too much space between them.

      Layout1.PNG

      I don't really want to use a label or anything like that to offset them because that could cause problems as the program is used on computers with different screen sizes. I guess what I'm really looking to understand is what tools do I have with PySides an QT that will allow me to control the placement of widgets within a layout but still allow for responsive design.

      alomA Offline
      alomA Offline
      alom
      wrote on last edited by alom
      #4

      @BD4L

      Heya,

      Yeah if you don't want the splitter you can just use a layout and set the setStretch factor
      https://doc.qt.io/qt-5/qboxlayout.html
      Just start two a simple widget with a layout and add two widget to it. Then play with setting the stretch to get a feel for the behavoir.

      For the radial button I use setMinimumSize(80, 20) for them, you can comment all these out first. Then the QSpacerItem "hor_spacer_center " is a fixed pixel amount to can control between the two radial buttons. Have a play with that to bring them closer together

      Cheers,

      Edit: expanding example

      from PySide2.QtWidgets import QHBoxLayout,QLineEdit, QListWidget,QSizePolicy, QApplication, QWidget
      
      from sys import exit as sysExit
      
      
      class Widget(QWidget):
          def __init__(self):
              QWidget.__init__(self)
      
              self.h_layout = QHBoxLayout()
              self.view = QListWidget()
              self.view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
              self.line = QLineEdit()
              self.line.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
              self.h_layout.addWidget(self.view, stretch=3)
              self.h_layout.addWidget(self.line, stretch=1)
              self.setLayout(self.h_layout)
      
      
      if __name__ == "__main__":
          MainEventHandler = QApplication([])
          application = Widget()
          application.show()
          sysExit(MainEventHandler.exec_())
      
      1 Reply Last reply
      2
      • alomA Offline
        alomA Offline
        alom
        wrote on last edited by
        #2

        Hi,

        Personally I find using Qt Designer and generating a .ui is always easier for me. Other people like to code it. I'll try my best at the ladder :P

        1. For this kind of stuff i have just been creating all four widgets at once then hide and unhided then base on signals generated from the buttons. In this case i connected the toggle signal to a custom function to manage the visible attribute.

        2. you can crate a horizontal spacer between the radial buttons and set its width to a fixed amount. I don't think I need to add the other two horizontal spacer here. We might be able to set an alignment policy on the layout to center the buttons, but I cant test that atm.

        3. I created a splitter and set the stretch factor to 3 time of the data_list_widget, splitters are also nice as the user can move the ui around if there is a long text.

        Hope that helps,

        If anyone has a clean layout let me know, I am lazy and use .ui all the time :P

        from PySide2.QtCore import Qt
        from PySide2.QtWidgets import QApplication, QWidget
        from PySide2.QtWidgets import QLineEdit, QListWidget, QLabel, QComboBox, QRadioButton
        from PySide2.QtWidgets import QSplitter, QSpacerItem, QSizePolicy
        from PySide2.QtWidgets import QHBoxLayout, QGridLayout, QGroupBox
        
        from sys import exit as sysExit
        
        
        class Widget(QWidget):
            def __init__(self):
                QWidget.__init__(self)
        
                self.left_grid_layout = QGridLayout()
                self.left_side_properties_grp = QGroupBox('Properties')
                self.grp_grid_layout = QGridLayout()
                self.left_side_properties_grp.setLayout(self.grp_grid_layout)
                
                self.h_layout = QHBoxLayout()
                self.new_radio_btn = QRadioButton("New")
                self.new_radio_btn.setMinimumSize(80, 20)
                self.new_le = QLineEdit()
                self.new_le.setMinimumSize(80, 20)
                self.load_radio_btn = QRadioButton("Load")
                self.load_radio_btn.setMinimumSize(80, 20)
                self.load_cbox = QComboBox()
                self.load_cbox.setMinimumSize(80, 20)
                self.load_cbox.addItems(['Shmee', 'Shmoo', 'Foo'])
                self.hor_spacer_l = QSpacerItem(2, 2, QSizePolicy.Expanding, QSizePolicy.Minimum)
                self.hor_spacer_center = QSpacerItem(30, 2, QSizePolicy.Fixed, QSizePolicy.Fixed)
                self.hor_spacer_r = QSpacerItem(2, 2, QSizePolicy.Expanding, QSizePolicy.Minimum)
                self.h_layout.addItem(self.hor_spacer_l)
                self.h_layout.addWidget(self.new_radio_btn)
                self.h_layout.addWidget(self.new_le)
                self.h_layout.addItem(self.hor_spacer_center)
                self.h_layout.addWidget(self.load_radio_btn)
                self.h_layout.addWidget(self.load_cbox)
                self.h_layout.addItem(self.hor_spacer_r)
                self.name_lb = QLabel("Name")
        
                self.name_le = QLineEdit()
                self.vertical_spacer = QSpacerItem(2, 2, QSizePolicy.Minimum, QSizePolicy.Expanding)
        
                self.grp_grid_layout.addLayout(self.h_layout, 0, 0)
                self.left_grid_layout.setAlignment(self.h_layout, Qt.AlignRight)
                self.grp_grid_layout.addWidget(self.name_lb)
                self.grp_grid_layout.addWidget(self.name_le)
                self.grp_grid_layout.addItem(self.vertical_spacer)
        
                self.data_list_widget = QListWidget()
                self.vert_splitter = QSplitter(Qt.Horizontal)
                self.vert_splitter.addWidget(self.data_list_widget)
                self.vert_splitter.addWidget(self.left_side_properties_grp)
                self.vert_splitter.setStretchFactor(0, 3)
                self.vert_splitter.setStretchFactor(1, 1)
        
                self.left_grid_layout.addWidget(self.vert_splitter)
        
                self.setLayout(self.left_grid_layout)
        
                self.new_le.setVisible(False)
                self.load_cbox.setVisible(False)
        
                self.new_radio_btn.toggled.connect(lambda: self.manage_buttons(True))
                self.load_radio_btn.toggled.connect(lambda: self.manage_buttons(False))
        
        
            def manage_buttons(self, toggle):
                self.new_le.setVisible(toggle)
                self.new_radio_btn.setVisible(not toggle)
                self.load_cbox.setVisible(not toggle)
                self.load_radio_btn.setVisible( toggle)
        
        
        if __name__ == "__main__":
            MainEventHandler = QApplication([])
        
            application = Widget()
            application.show()
        
            sysExit(MainEventHandler.exec_())
        
        1 Reply Last reply
        1
        • B Offline
          B Offline
          BD4L
          wrote on last edited by
          #3

          @alom @Denni-0

          Hey friends thanks for the quick responses. These are really helpful. The toggles work great for displaying only the fields I want to show, and I really like the vertical spacer that alom used but I'm wondering if there's a way to make it so users can't move the spacer to adjust the size of the column.

          The one thing that still doesn't seem to be working is centering the radio buttons in their layout area. When the view is stretched the radio buttons are shifted left of center with too much spacing between them:

          Layout2.PNG

          When the view is more compact the New button is left justified instead of centered and there's still too much space between them.

          Layout1.PNG

          I don't really want to use a label or anything like that to offset them because that could cause problems as the program is used on computers with different screen sizes. I guess what I'm really looking to understand is what tools do I have with PySides an QT that will allow me to control the placement of widgets within a layout but still allow for responsive design.

          alomA 1 Reply Last reply
          0
          • B BD4L

            @alom @Denni-0

            Hey friends thanks for the quick responses. These are really helpful. The toggles work great for displaying only the fields I want to show, and I really like the vertical spacer that alom used but I'm wondering if there's a way to make it so users can't move the spacer to adjust the size of the column.

            The one thing that still doesn't seem to be working is centering the radio buttons in their layout area. When the view is stretched the radio buttons are shifted left of center with too much spacing between them:

            Layout2.PNG

            When the view is more compact the New button is left justified instead of centered and there's still too much space between them.

            Layout1.PNG

            I don't really want to use a label or anything like that to offset them because that could cause problems as the program is used on computers with different screen sizes. I guess what I'm really looking to understand is what tools do I have with PySides an QT that will allow me to control the placement of widgets within a layout but still allow for responsive design.

            alomA Offline
            alomA Offline
            alom
            wrote on last edited by alom
            #4

            @BD4L

            Heya,

            Yeah if you don't want the splitter you can just use a layout and set the setStretch factor
            https://doc.qt.io/qt-5/qboxlayout.html
            Just start two a simple widget with a layout and add two widget to it. Then play with setting the stretch to get a feel for the behavoir.

            For the radial button I use setMinimumSize(80, 20) for them, you can comment all these out first. Then the QSpacerItem "hor_spacer_center " is a fixed pixel amount to can control between the two radial buttons. Have a play with that to bring them closer together

            Cheers,

            Edit: expanding example

            from PySide2.QtWidgets import QHBoxLayout,QLineEdit, QListWidget,QSizePolicy, QApplication, QWidget
            
            from sys import exit as sysExit
            
            
            class Widget(QWidget):
                def __init__(self):
                    QWidget.__init__(self)
            
                    self.h_layout = QHBoxLayout()
                    self.view = QListWidget()
                    self.view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
                    self.line = QLineEdit()
                    self.line.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
                    self.h_layout.addWidget(self.view, stretch=3)
                    self.h_layout.addWidget(self.line, stretch=1)
                    self.setLayout(self.h_layout)
            
            
            if __name__ == "__main__":
                MainEventHandler = QApplication([])
                application = Widget()
                application.show()
                sysExit(MainEventHandler.exec_())
            
            1 Reply Last reply
            2

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved