0

I need to set:

-minimum height for a cell in QTreeView (25px)
-the height and width to fit with the content of each cell.

I know that we can do it with sizeHint() in Delegate or with sizeHintRole in Model but still can not imagine how the functions should look like. This is paint() in my Delegate:

const int marginLeft = 10; // margin between text in each cell with the left border
const int marginLeftFirstColumn = 20; //margin between text and the left border in the first column
const int marginRight = 10;

void TableDelegate::paint( QPainter *p_painter, const QStyleOptionViewItem &p_option, const QModelIndex &p_index ) const
{
  QStyleOptionViewItem option = p_option;

  TableDataRow::Type type = static_cast<TableDataRow::Type>( p_index.data( Qt::UserRole ).toInt() );

  QString text = p_index.data( Qt::DisplayRole ).toString();
  QFont font = p_painter->font();
  int col = p_index.column();

  switch ( type )
  {
     case TableDataRow::Type::Data:
     {
        font.setWeight( QFont::Normal );
        p_painter->setFont( font );
        if ( col == 0 )
        {
           option.rect.setRect( option.rect.left() + marginLeftFirstColumn, option.rect.top(), option.rect.width() - marginRight, option.rect.height() );
        }
        else
        {
           option.rect.setRect( option.rect.left() + marginLeft, option.rect.top(), option.rect.width() - marginRight, option.rect.height() );
        }
        break;
     }
     case  TableDataRow::Type::MainCaption:
     {
        p_painter->fillRect( p_option.rect, Qt::gray ); //draw background
        font.setWeight( QFont::Bold );
        p_painter->setFont( font );
        option.rect.setRect( option.rect.left() + marginLeft, option.rect.top(), option.rect.width() - marginRight, option.rect.height() );
        break;
     }
  }
  p_painter->drawText( option.rect, Qt::AlignVCenter | Qt::TextWordWrap, text );
}

QSize TableDelegate::sizeHint( const QStyleOptionViewItem &p_option, const QModelIndex &p_index ) const //this function to compensate the alignment
{
  QSize size = QStyledItemDelegate::sizeHint( p_option, p_index );
  if ( p_index.column() == 0 )
     {
        size.setWidth( size.width() + marginLeftFirstColumn );
     }
     else
     {
        size.setWidth( size.width() + marginLeft );
     }
  return size;
}

Could you guys help me with data() function in Model and update sizeHint() in Delegate?

songvan
  • 369
  • 5
  • 21
  • I would use your table's model and `Qt::SizeHintRole` approach. In your model's `data()` function you should return the size that correspond to cells you want to enlarge. – vahancho Aug 14 '18 at 07:33
  • @vahancho: thanks for your idea. Problem is I don't know how to return the size here. Function data() looks like this `data( const QModelIndex &p_index, int p_role )`. How should I return the size with `p_index` here, could you tell me with the code here pls? – songvan Aug 14 '18 at 07:37

1 Answers1

1

Here is a rough example on how to set size for particular table cell using QAbstractItemModel::data() function:

QVariant MyModel::data(const QModelIndex & index, int role) const
{
  if (role == Qt::SizeHintRole)
  {
    // An example. Set the size of the first cell.
    if (index.row() == 0 && index.column() == 0)
    {
      return QSize(100, 100);
    }
  }
  else if (role == Qt::DisplayRole)
  {
    // Manage how item should appear.
  }
  return QAbstractItemModel::data(index, role);
}
vahancho
  • 20,808
  • 3
  • 47
  • 55
  • thank you! but problem here is the size of each cell should be fit with the content. So it can not be set with a fixed number like this. Therefore I can not imagine how the function should look like :) – songvan Aug 14 '18 at 07:57
  • Hm, if it's about content, why don't you use `QTableView::resizeColumnToContents()` function? – vahancho Aug 14 '18 at 08:01
  • 1
    I set it already. :) In this case I set `option.rect.setRect` in my delegate. So the text sometimes will be cut. But I have updated my sizeHint() so it works now. But the problem is, how can I set the height of row to fit with content because in delegate i set textWordWrap already `p_painter->drawText( option.rect, Qt::AlignVCenter | Qt::TextWordWrap, text );`. And how can I set the minimum height for the row? I updated my code above. – songvan Aug 14 '18 at 08:37