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. Is there a way to set size hints?
Forum Updated to NodeBB v4.3 + New Features

Is there a way to set size hints?

Scheduled Pinned Locked Moved Unsolved Qt for Python
8 Posts 2 Posters 4.0k Views 1 Watching
  • 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.
  • D Offline
    D Offline
    deanhystad
    wrote on last edited by
    #1

    I have a composite widget consisting of a prefix label, suffix label, and some kind of control between the two. I would like to place several of these widgets in a vertical layout box and have the parts line up. Ideally I would like to set the size hints so all the prefixes had the same hint, all the suffixes the same hint, and all the controls the same hint.

    Is there any way to do that?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      One way is to have a function that you call to insert the labels in the layout.

      Another one is to subclass the layout and add methods to it to add these labels that will set the properties to suitable values.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • D Offline
        D Offline
        deanhystad
        wrote on last edited by
        #3

        I am using a grid layout. I am able to make things work with dastardly doings.

        mport sys
        from PySide2.QtWidgets import QGridLayout, QLabel, QApplication, QWidget, QLineEdit, QPushButton
        from PySide2.QtCore import Qt
        
        class Labeled_LineEdit(QWidget):
            """Three labels"""
            def __init__(self, label, text):
                super().__init__()
                self.prefix = QLabel(label)
                self.edit = QLineEdit()
                self.edit.setText(text)
                self.grid = QGridLayout(self)
                self.grid.addWidget(self.prefix, 0, 0)
                self.grid.addWidget(self.edit, 0, 1)
                self.grid.setColumnStretch(0, 0)
                self.grid.setColumnStretch(1, 1)
        
            def same_as(self, pattern):
                """Make my layout like pattern"""
                self.prefix.sizeHint = pattern.prefix.sizeHint
                self.edit.sizeHint = pattern.edit.sizeHint
        
        class MyPanel(QWidget):
            def __init__(self):
                """Demo my layout problem"""
                super().__init__()
                self.a = Labeled_LineEdit('Longer label', 'A')
                self.b = Labeled_LineEdit('Short', 'B')
                self.b.same_as(self.a)
                self.grid = QGridLayout(self)
                self.grid.addWidget(self.a, 0, 0)
                self.grid.addWidget(self.b, 1, 0)
        
        app = QApplication(sys.argv)
        main = MyPanel()
        main.show()
        sys.exit(app.exec_())
        

        This quite literally copies the size hints from one widget and applies them to another, but I know there has to be a better way.

        Are you are suggesting that I subclass the grid layout used here so when it asks for widget size hints I can provide the hints that I want? I like that idea.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Sorry, I misunderstood what you were meaning by size hints with layouts.

          Looks like you want something a bit like QFormLayout ?

          In any case, if you want all your widgets to have the same size, then at some point you'll have have one that serves as reference and then resize the others to match.

          Here what you do in Python is nasty in the sense that you replace all the widgets sizeHint methods with the one from the "pattern".

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • D Offline
            D Offline
            deanhystad
            wrote on last edited by
            #5

            Nothing conveys information as well as code.

            I don't think I can use QFormLayout. My example is oversimplified and the actual widgets I am trying to align are a bit more complicated. For example, I have a widget with QLineEdit and a slider, min and max labels for the slider tic marks, a prefix and a suffix label. The slider extends from the left of the prefix widget to the right of the QLineEdit. I also have a radio button cluster which has a lot of parts to align.

            I do not like monkeypatching the sizeHint methods. That kind of thing will eventually lead to trouble. But I thought this would give you a good idea of what I am trying to achieve. Now I just need a better way of doing it.

            I've been looking at the grid layout and am not seeing where I could override the "get sizeHint" behavior. Any hints?

            1 Reply Last reply
            0
            • D Offline
              D Offline
              deanhystad
              wrote on last edited by
              #6

              How do I tell the layout to update? I think the update() method call in the same_as method is telling the grid in the parent window to update. I want to update the grid layout in the Labeled_Control widget.

              I modified the sizeHint monkey patch to be less horrible and this works well most of the time. Occasionally see a problem where one of the widgets is off by a couple of pixels after I call same_as(). If I do something to force the grid layout to update (like set the label text) then all the widgets align.

              import sys
              from functools import partial
              from PySide2.QtWidgets import QGridLayout, QLabel, QApplication, QWidget, QLineEdit, QPushButton
              from PySide2.QtCore import Qt
              
              class Labeled_Control(QWidget):
                  """Three labels"""
                  def __init__(self, label, text):
                      super().__init__()
                      self.size_ref = None
                      self.parts = [None, None]
                      self._partSizeHint = [None, None]
                      self.prefix = QLabel(label)
                      self.control = QLineEdit()
                      self.control.setText(text)
                      self.grid = QGridLayout(self)
                      self.grid.addWidget(self.prefix, 0, 0)
                      self.grid.addWidget(self.control, 0, 1)
                      self.grid.setColumnStretch(0, 0)
                      self.grid.setColumnStretch(1, 1)
              
                  @property
                  def prefix(self):
                      return self.parts[0]
              
                  @prefix.setter
                  def prefix(self, widget):
                      self.set_part(0, widget)
              
                  @property
                  def control(self):
                      return self.parts[1]
              
                  @control.setter
                  def control(self, widget):
                      self.set_part(1, widget)
              
                  def set_part(self, index, widget):
                      """Set part[index] = widget"""
                      part = self.parts[index]
                      if part:
                          # Restore part's sizeHint method
                          part.sizeHint = self._partSizeHint[index]
                          self._partSizeHint[index] = None
                      self.parts[index] = widget
                      if widget:
                          # Override widget's sizeHint method
                          self._partSizeHint[index] = widget.sizeHint
                          widget.sizeHint = partial(self.partSizeHint, index)
              
                  def partSizeHint(self, index):
                      """Return size hint for part[index]"""
                      if self.size_ref:
                          return self.size_ref.partSizeHint(index)
                      return self._partSizeHint[index]()
              
                  def same_as(self, pattern):
                      """Make my layout like pattern"""
                      self.size_ref = pattern
                      self.grid.update()
              
              class MyPanel(QWidget):
                  def __init__(self):
                      """Demo my layout problem"""
                      super().__init__()
                      self.a = Labeled_Control('Longer label', 'A')
                      self.b = Labeled_Control('Short', 'B')
                      self.b.same_as(self.a)
                      self.grid = QGridLayout(self)
                      self.grid.addWidget(self.a, 0, 0)
                      self.grid.addWidget(self.b, 1, 0)
                      self.b.same_as(self.a)
              
              app = QApplication(sys.argv)
              main = MyPanel()
              main.show()
              sys.exit(app.exec_())
              
              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                You might want to consider using a QHBoxLayout and play with the stretch factor to give more or less space to your widgets.

                For QFormLayout, I was rather suggesting to take a look St its implementation as a source of idea for yours.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  deanhystad
                  wrote on last edited by
                  #8

                  I have reasons for using a grid that are not shown in this simple example. Widgets can be aligned vertically or horizontally. Some Labeled_Controls have more than 1 row of widgets. The flexibility of the grid layout makes this easier. I tried using combinations of horizontal and vertical box layouts. That turned out more complicated and the results were not good.

                  I will investigate using setColumnWidth for the grid layout.

                  I really wish I could find a way to tell the grid layout to update . This works but I cannot stand it.

                      def same_as(self, pattern):
                          """Make my layout like pattern"""
                          self.size_ref = pattern
                          self.prefix.setText(self.prefix.text())  # Yuck!
                  
                  1 Reply Last reply
                  0

                  • Login

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