Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Unsolved How to make QTableView to adjust the height of it's horizontal header automatically in PyQt?

    Qt for Python
    pyside2 qt for python
    2
    13
    3287
    Loading More Posts
    • 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.
    • T
      ThePyGuy @SGaist last edited by

      @SGaist Hi SGiast, you seem to appear online, I'd be very grateful if you help me out, and point me to the right direction.

      SGaist 1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion @ThePyGuy last edited by

        One thing which is not good in your model is that you never call the base class implementation of the methods you override for the cases you do not handle. This means that you do not let the standard flow happen.

        I don't have a machine at hand right now, I'll test this later.

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

        T 1 Reply Last reply Reply Quote 0
        • T
          ThePyGuy @SGaist last edited by

          @SGaist I tried to take out the code from the actual project to be used as sample, so I might have forgot to implement calling the base classes for the overridden method for the cases that I'm not handling, anyways, please let me know when you are done with the testing, Thank you for your response! I'll be looking forward to hearing from you.

          1 Reply Last reply Reply Quote 0
          • SGaist
            SGaist Lifetime Qt Champion last edited by

            Here is a simple implementation that gets you what you want.

            Note that you can nuke your resizeColumns parts completely.

            class HeaderView(QHeaderView):
                def __init__(self, parent=None):
                    super().__init__(Qt.Horizontal, parent=parent)
                    self.setStyleSheet(
                        "QHeaderView::section{background-color: #ffffff; "
                        "font-weight: bold; "
                        "padding-left: 2px; "
                        "color: #3467ba; "
                        "border:0px; "
                        "border-left: 1px solid #ababab; "
                        "border-bottom: 1px solid gray;}"
                    )
                    self.setStretchLastSection(True)
                    self.setDefaultAlignment(Qt.AlignCenter | Qt.Alignment(Qt.TextWordWrap))
            
                def sectionSizeFromContents(self, logicalIndex):
                    text = self.model().headerData(logicalIndex, self.orientation(), Qt.DisplayRole)
                    alignment = self.defaultAlignment()
                    metrics = QFontMetrics(self.fontMetrics())
                    rect = metrics.boundingRect(QRect(), alignment, text)
                    return rect.size()
            

            On a side note TableView is really not needed here. In fine, you only "configure" it, so there's no need to subclass it.

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

            T 1 Reply Last reply Reply Quote 0
            • T
              ThePyGuy @SGaist last edited by

              @SGaist Thanks for your response, Yes, I don't need to subclass QTableView, but I need to use the same table at multiple places that is why I sub-classed it. This function sectionSizeFromContents that you overwrote is able to provide the bounding rectangle but it is always constant even if the width of the header section is resized, which is understandable because it is taking only the text and alignment into account and trying to estimate the bounding rectangle for it, and I think it is useful to define some minimum width.
              What I want is to increase/decrease the height of the header whenever the width of a header section is changed; each section will have their own width, but the height needs to be the maximum of the heights required by the sections.
              i.e. for example, let's say there are 5 columns with widths: 60, 100, 80, 75, 90, and height required as: 30,40,50,30,30, then the height of the header needs to be 50 i.e. maximum among 30,40,50,30,30.
              Now let's say user resized a section (2nd section for example) from 100 to 160, then required height for this section will obviously decrease since width for this section increased, let's say required height changed from 50 to 35, then the required heights are 30,40,35,30,30, and maximum of it is 40, so the new height for the header will be 40.

              1 Reply Last reply Reply Quote 0
              • SGaist
                SGaist Lifetime Qt Champion last edited by

                What about getting the size of the other sections to create the reference size ?

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

                T 2 Replies Last reply Reply Quote 0
                • T
                  ThePyGuy @SGaist last edited by ThePyGuy

                  @SGaist At a time, the user is able to resize only a single column since the resizing is going to happen through mouse, so anytime a column width is resized, the minimum required height for the resized column needs to be calculated, and it should be checked against the minimum height required for all other columns, and whichever is the maximum value, that becomes the current new height of the header.

                  1 Reply Last reply Reply Quote 0
                  • T
                    ThePyGuy last edited by

                    This post is deleted!
                    1 Reply Last reply Reply Quote 0
                    • T
                      ThePyGuy @SGaist last edited by

                      @SGaist Can you please help me with this? You seem to be the only hope I have.

                      1 Reply Last reply Reply Quote 0
                      • SGaist
                        SGaist Lifetime Qt Champion last edited by

                        Try with:

                        MAX_HEIGHT = 4096  # Arbitrary value
                        
                        class HeaderView(QHeaderView):
                            def __init__(self, parent=None):
                                super().__init__(Qt.Horizontal, parent=parent)
                                self.setStyleSheet(
                                    "QHeaderView::section{background-color: #ffffff; "
                                    "font-weight: bold; "
                                    "padding-left: 2px; "
                                    "color: #3467ba; "
                                    "border:0px; "
                                    "border-left: 1px solid #ababab; "
                                    "border-bottom: 1px solid gray;}"
                                )
                                self.setStretchLastSection(True)
                                self.setDefaultAlignment(Qt.AlignCenter | Qt.Alignment(Qt.TextWordWrap))
                        
                            def sectionSizeFromContents(self, logicalIndex):
                                text = self.model().headerData(logicalIndex, self.orientation(), Qt.DisplayRole)
                                alignment = self.defaultAlignment()
                                metrics = QFontMetrics(self.fontMetrics())
                                width = metrics.boundingRect(QRect(), alignment, text).width()
                        
                                heights = []
                                for i in range(self.count()):
                                    text = self.model().headerData(i, self.orientation(), Qt.DisplayRole)
                                    size = self.sectionSize(i)
                                    rect = QRect(0, 0, size, MAX_HEIGHT)
                                    heights.append(metrics.boundingRect(rect, alignment, text).height())
                                height = sorted(heights)[-1]
                                return QSize(width, height)
                        

                        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 Reply Quote 0
                        • First post
                          Last post