Adjusting the height of rows in QTableView



  • I need to adjust the height of rows in a QTableView on a per-row basis. Summerfield says that there are two methods. One is "to return a suitable size hint when data() is called with the Qt.SizeHintRole". The other is to "reimplement the QItemDelegate.sizeHint() method". In the attached test program, data never receives Qt.SizeHintRole and the delegate never gets called after being instantiated. The first method may apply only to adjustments to the width, but I believe that a delegate should be able to adjust both width and height by overriding sizeHint. What am I missing?

    """I want to control the height of each row, but I never get
    SizeHintRole in data nor is ListerDelegate called."""
    
    from PySide2.QtCore import QAbstractTableModel, QModelIndex, Slot
    from PySide2.QtWidgets import QApplication, QWidget, QTableView
    from PySide2.QtWidgets import QVBoxLayout, QStyledItemDelegate
    from PySide2.QtGui import Qt
    
    class ListerModel(QAbstractTableModel):
        def __init__(self):
            super().__init__()
            self.rows = [("one", "two"), ("three", "four"), ("five", "six")]
    
        def rowCount(self, index=QModelIndex()):
            return 3
    
        def columnCount(self, index=QModelIndex()):
            return 2
    
        def data(self, index, role=Qt.DisplayRole):
            row = self.rows[index.row()]
            column = index.column()
            if role == Qt.DisplayRole:
                return row[column]
            elif role == Qt.SizeHintRole:
                print("got SizeHintRole")
    
    class ListerDelegate(QStyledItemDelegate):
        def __init__(self, parent):
            super().__init__(parent)
            print("In ListerDelegate.__init__")
    
        def __getattr__(self, attr):
            print("In ListerDelegate.__getattr__", attr)
            return getattr(QStyledItemDelegate, attr)
    
    if __name__ == "__main__":
        class Tester(QWidget):
            def __init__(self):
                super().__init__()
    
                lister_model = ListerModel()
                view = QTableView()
                view.setModel(lister_model)
                delegate = ListerDelegate(self)
                view.setItemDelegate(delegate)
    
                vbox = QVBoxLayout()
                vbox.addWidget(view)
                self.setLayout(vbox)
    
        app = QApplication()
        testerwindow = Tester()
        testerwindow.show()
        app.exec_()
    


  • Apparently, one needs to explicitly request a resize, e.g., with view.resizeColumnToContents(0) after the setItemDelegatestatement. It seems to me that the delegate would be invoked when sizing the view initially, but evidently this expectation is wrong.

    Also, it appears that __getattr__ does not work in PySide2.


Log in to reply