Установить размер ячейки в QTreeView

Мне нужно установить:

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

Я знаю, что мы можем сделать это с помощью sizeHint() в делегате или с помощью sizeHintRole в модели, но все еще не могу представить, как должны выглядеть функции. Это paint() в моем делегате:

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;
}

Не могли бы вы, ребята, помочь мне с функцией data() в модели и обновить sizeHint() в делегате?


person songvan    schedule 14.08.2018    source источник
comment
Я бы использовал модель вашей таблицы и подход Qt::SizeHintRole. В функции data() вашей модели вы должны вернуть размер, соответствующий ячейкам, которые вы хотите увеличить.   -  person vahancho    schedule 14.08.2018
comment
@vahancho: спасибо за идею. Проблема в том, что я не знаю, как вернуть размер здесь. Функция data() выглядит так data( const QModelIndex &p_index, int p_role ). Как мне вернуть размер с помощью p_index здесь, не могли бы вы сказать мне код здесь, пожалуйста?   -  person songvan    schedule 14.08.2018


Ответы (1)


Вот грубый пример того, как установить размер для конкретной ячейки таблицы с помощью функции QAbstractItemModel::data():

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);
}
person vahancho    schedule 14.08.2018
comment
спасибо! но проблема здесь в том, что размер каждой ячейки должен соответствовать содержимому. Таким образом, это не может быть установлено с фиксированным числом, подобным этому. Поэтому я не представляю, как должна выглядеть функция :) - person songvan; 14.08.2018
comment
Хм, если речь идет о контенте, почему бы вам не использовать функцию QTableView::resizeColumnToContents()? - person vahancho; 14.08.2018
comment
Я уже поставил. :) В этом случае я установил option.rect.setRect в своем делегате. Так что текст иногда будет обрезан. Но я обновил свой sizeHint(), так что теперь он работает. Но проблема в том, как я могу установить высоту строки в соответствии с содержимым, потому что в делегате я установил textWordWrap уже p_painter->drawText( option.rect, Qt::AlignVCenter | Qt::TextWordWrap, text );. И как я могу установить минимальную высоту для строки? Я обновил свой код выше. - person songvan; 14.08.2018