PDA

View Full Version : QStyledItemDelegate.sizeHint() works only if my TableModel has rows



AlexVhr
12th April 2013, 17:15
Hi! I've a usual TableView-TableModel-Delegate setup, and use Delegate.sizeHint() to control column width. It works perfectly, but only when my model has rows. If it's empty, then columns have default width, which is not good. What can be the couse of it? Full test case follows (python):


import sys
from PySide import QtGui, QtCore

class Person:
def __init__(self, f_name, l_name, country):
self.f_name = f_name
self.l_name = l_name
self.country = country

class MyDelegate(QtGui.QStyledItemDelegate):
def sizeHint(self, option, index):
super().sizeHint(option, index)
width = index.model().sizes[index.column()]
return QtCore.QSize(width, 24)

class MyModel(QtCore.QAbstractTableModel):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.columns = ['f_name','l_name', 'country']
self.sizes = [70, 70, 35]
self.rows = [Person('John', 'Doe', 'USA'),
Person('Hans', 'Mann', 'DE')]
#self.rows = [] #uncomment this to see it fail

def rowCount(self, *args, **kwargs):
return len(self.rows)

def columnCount(self, *args, **kwargs):
return len(self.columns)

def data(self, index, role):
if index.isValid():
if role == QtCore.Qt.DisplayRole:
row = self.rows[index.row()]
col = self.columns[index.column()]
attr = getattr(row, col)
return attr

if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
win = QtGui.QTableView()
win.setModel(MyModel())
win.setItemDelegate(MyDelegate(win))
win.resizeColumnsToContents()
win.show()
sys.exit(app.exec_())

wysota
12th April 2013, 17:37
sizeHint() needs a valid index. If you don't have rows in your table, what are you calling sizeHint() on?

AlexVhr
12th April 2013, 17:56
Sounds logical, thanks. So I guess setting column width within delegates is a wrong approach in my case.

wysota
12th April 2013, 20:48
It depends what you want to do. If you program your delegate to return some size for an invalid index and you make sure the view calls your delegate when it has no rows to show, then you can do that.

AlexVhr
13th April 2013, 07:41
I want nothing fancy - just need to set column width from outside the model. Delegate seemed to be a logical choice. So about that "make sure the view calls your delegate when it has no rows to show" bit - how whould I go about that? Can I realy influence when and how the view invokes the delegate?

wysota
13th April 2013, 08:32
I want nothing fancy - just need to set column width from outside the model. Delegate seemed to be a logical choice.
You can set the column size by accessing the header object directly (QHeaderView::setDefaultSectionSize()).

AlexVhr
13th April 2013, 12:16
But it only got one argument - default size for all sections of the header. I however need to set the size individually (line 13 in my example code above)

Added after 10 minutes:

Anyway, I got what I wanted using TableView.horizontalHeader().resizeSection(c, size). That does not fit into 'do it with delegate' approach, but I can live with that.