2

I am using a QTableView to display user activity in my application.

My model contains four columns, each column displays a different type of text like:

  • username in the 1st column
  • user activity in the 2nd column
  • details of activity in the 3rd column

I want to display both the text of 2nd and 3rd columns in a single column with a different text color separated with a "-".

My application currently looks like this:

enter image description here

However, I want it to look similar to this

enter image description here

Can someone please help me to solve this out, thanks in advance

Steve Lorimer
  • 27,059
  • 17
  • 118
  • 213
Sanath Reddy
  • 900
  • 2
  • 7
  • 13

2 Answers2

1

I would approach to this topic in two steps:

  1. change model in such way that 2nd and 3rd columns are a single column but value from old 2nd column is returned as Qt:DisplayRole (standard way) and value from old 3rd column is returned for Qt::SomeUserRole
  2. Add delegate to table view which will handle visualization of merged columns and display item in "gmail" style. Values for visualization are fetched form model using respective role values from previous step.

You can also treat the whole thing as a list with lots of different data roles: each row as a single item (this could be handled very nicely in qml).

Marek R
  • 32,568
  • 6
  • 55
  • 140
1

You can override data method of your model and return custom color with Qt::ForegroundRole for necessary columns.

But if you like "gmail" visualisation - than you should create your own delegate (as proposed by @Marek). You may use QTextDocument for advanced text rendering. Pseudo-code:

void QStyledItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
  painter->save();

  const QString title = index.model()->data( YourTitleRoleId ).toString();
  const QString content = index.model()->data( YourContentRoleId ).toString();
  // Use any qt-supported html tags
  const QString html = QString( "<html><b>%1</b> - <i>%2</i></html>" ).arg( title ).arg( content );
  QTextDocument doc;
  doc.setHtml( html );
  QRectF rc( option.rect );
  doc.drawContents( painter, rc );

  painter->restore();
}

Feel free to ask, if something is not clear.

Steve Lorimer
  • 27,059
  • 17
  • 118
  • 213
Dmitry Sazonov
  • 8,801
  • 1
  • 35
  • 61
  • I tried to repeat your example here. I've checked that my HTML is valid, however, I'm getting a blank cell in my table view. Are you sure this is correct? – Steve Lorimer May 25 '16 at 18:57
  • I used `painter->translate` and a `QRect` as detailed [here](http://stackoverflow.com/questions/17114944/qstyleditemdelegate-rendering-qtextdocument-rich-text-doesnt-alignhcenter) and that worked – Steve Lorimer May 25 '16 at 19:07
  • @SteveLorimer what is "valid html"? Qt supports only restricted subset of html. See docs. – Dmitry Sazonov May 25 '16 at 22:28
  • I mean that that wasn't the problem. As mentioned in a later comment, changing QRectF to QRect with coords from painter->translate worked. Not sure if it's the QRectF to QRect or the translated coords that were the fix. – Steve Lorimer May 26 '16 at 03:00
  • The QStyledItemDelegate::sizeHint() also needs updating to return the QSize required by the layout of the QTextDocument using doc.documentLayout().documentSize().toSize(). – JPh Apr 11 '19 at 11:11