Solved 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 thesetItemDelegate
statement. 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.