PDA

View Full Version : How can I change row heigth in QTableView?



Tamara
14th February 2007, 12:45
QTableView has a very usefull function - resizeRowsToContents(). But there is one problem: while using it, rows become much higher (approximetly 40 % higher) than it is needed to be able to read the text contained in the cell)
I want to continue use resizeRowsToContents(), but I want to make rows lower, to make this "spacing" between text and cell border smaller.
Can I do it in some way?

Moppel
14th February 2007, 13:23
I would guess you need to return the size you want from the data function of your model
http://doc.trolltech.com/4.2/qabstractitemmodel.html#data
when the Qt::SizeHintRole is requested (http://doc.trolltech.com/4.2/qt.html#ItemDataRole-enum)

HTH,

M.

Tamara
14th February 2007, 17:21
The problem is that in such case I would have to set size to all rows, according to cell string amount (I want to use word wrap in the table), while resizeRowToContext makes this work it self.
But may be I can use sizeHintRole in some other way....
If data()-function is called (from library) after rows heights are initialized, I would only have to multiply heights with some factor(about 0.7)...
Can I do it in such way?

baca
15th February 2007, 19:47
It can looks like:

1) first prepare class:


class CTreeDelegate : public QItemDelegate
{
Q_OBJECT

public:
CTreeDelegate(QObject *parent) : QItemDelegate(parent)
{
}

QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QSize s = QItemDelegate::sizeHint(option, index);
s.setHeight(row_height);
return s;
}

void setRowHeight(const unsigned char height)
{
row_height = height;
}

protected:
unsigned char row_height;
};
or if you wan't change height at run apps:


class CTreeDelegate : public QItemDelegate
{
Q_OBJECT

public:
CTreeDelegate(QObject *parent, unsigned char height) : QItemDelegate(parent), row_height(height)
{
}

QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QSize s = QItemDelegate::sizeHint(option, index);
s.setHeight(row_height);
return s;
}

protected:
const unsigned char row_height;
};
2) and add the class to your tree:



CTreeDelegate *delegate = new CTreeDelegate(this);
delegate->setRowHeight(25); // for example 25

QTreeWidget *tree = new QTreeWidget(this));
tree->setItemDelegate(delegate);

Tamara
16th February 2007, 09:44
No, I know all this stuff. And I also I know how to do what I want by using QTreeView much simpler. But I don't want to use treeview! I want to use tableView.
And I want only to reduce row height AFTER it is initialized by library (after resizeRowToContext() is called)
I want to do something like this (this code-fragment should be from ItemModel):


Python:
def data(self, index):
...
if QtCore.Qt.SizeHintRole == role:
size = super(MyListModel, self).data(index, QtCore.Qt.SizeHintRole)
if size.toInt() > 5:
return QtCore.QVariant(size.toInt() - 5)
else:
return size
...

C++:
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const {
...
if (Qt::SizeHintRole == role){
QVariant size = data(index, Qt::SizeHintRole);
if (size.toInt() > 5)
return QVariant(size.toInt() - 5);
else
return size;
}
...
}


But I can't do like that due to data()-function from QAbstractItemModel is pure virtual :(
May be there is another way to learn from data() size of a row?

jpn
16th February 2007, 14:38
Do the heights vary from row to row? If not, try the suggestion in this post (http://www.qtcentre.org/forum/p-qtableview-question-post28352/postcount2.html).

Tamara
19th February 2007, 16:36
Thank you. Rows heights can be different depending on strings amount, but may be it can help me as multiline rows are rather rare in the table.
The one problem is that in this case such rows may be will look unpleasant... But I'll try

wysota
19th February 2007, 17:28
To sum things up, there are three (or four, including jpn's solution) ways to set a size of an item:

1. set Qt::SizeHintRole for items
2. return the size from within data() for the SizeHintRole
3. reimplement the delegate and overload sizeHint()

All these three are taken into consideration by the view when determining cell size so you may use which one you want (or all of them). AFAIR solution 1. has the highest priority ("item knows best"), 2. has the middle priority ("model knows best") and solution 3. has the lowest priority ("stupid model, let's ask the delegate"). Of course the delegate can ask the model for item size and the model can ask the item for size (that's where the precedence comes from), so you may have varieties of results.


But I can't do like that due to data()-function from QAbstractItemModel is pure virtual :(
May be there is another way to learn from data() size of a row?

You can always ask the base class of the model for the size hint. Remember, that there always is a base class that actually has data() implemented - as you can't modify one of existing classes, you can only build on top of it, meaning that the base will be one of QAbstractItemModel subclasses that implements the method. The only difference is when you directly subclass QAbstractItemModel or other abstract class. But then it doesn't make sense to ask the model for size, as there is no model beneath - let the view care then (the "stupid model" case)...

An intermediate solution (which is really solution 2.) is to have a proxy model which you wrap over the real model and pass the proxy to the view. This way you can have different results by changing the proxy and not having to subclass the real model.

fjh
18th August 2011, 21:41
I too found the default row height was more than I wanted. The culprit seemed to be the vertical header, even though it was turned off. My fix was:

1. Set the minimum header section size to something small, like 1. In Qt Designer it's called verticalHeaderMinimumSectionSize or in code you probably call QHeaderView.setMinimumSectionSize().

2. Turn on resizing - could not find this in Qt Designer, so had to do it in code. (This is python - I'm using PySide - but it should be clear to anyone).

tableview.verticalHeader().setResizeMode(QHeaderVi ew.ResizeMode.ResizeToContents)


3. In the model, return a small size for row headers. The rows won't actually be this small, as they are also sized to fit their contents.

def headerData(self, i, orient, role):
if role==Qt.SizeHintRole and orient==Qt.Orientation.Vertical: return 1
...