Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] QTableView - custom sizeHint() implementation slow

[SOLVED] QTableView - custom sizeHint() implementation slow

Scheduled Pinned Locked Moved General and Desktop
4 Posts 2 Posters 3.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    aran
    wrote on last edited by
    #1

    Hi guys,

    I'm using a QTableView to display a bunch of information. Since I need rich text support in the cells I implemented a custom item delegate with QTextDocument and overwrote the sizeHint();
    However, the sizeHint() function causes some problems: It slows everything down really badly. By that I mean, that e.g. moving the cursor over a few cells, the highlighting really lags behind.

    Here's the code that I use for the Delegate and the sizeHint:
    @void RichTextDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {

    QStyleOptionViewItemV4 options = option;
    initStyleOption(&options, index);

    painter->save();

    QTextDocument doc;
    doc.setTextWidth(options.rect.width());
    doc.setHtml(options.text);

    options.text = "";
    options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter);

    painter->translate(options.rect.left(), options.rect.top());
    QRect clip(0, 0, options.rect.width(), options.rect.height());

    QPen greyPen(Qt::lightGray);
    painter->setPen(greyPen);
    painter->drawLine(0,options.rect.height(),options.rect.width(),options.rect.height());
    painter->drawLine(0,0,options.rect.width(),0);

    painter->setClipRect(clip);
    QAbstractTextDocumentLayout::PaintContext ctx;

    ctx.clip = clip;
    doc.documentLayout()->draw(painter, ctx);

    painter->restore();

    }

    QSize RichTextDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const {

    QStyleOptionViewItemV4 optionV4 = option;
    initStyleOption(&optionV4, index);
    QTextDocument doc;
    doc.setHtml(optionV4.text);
    doc.setTextWidth(optionV4.rect.width());
    return QSize(doc.idealWidth(), doc.size().height());

    }@

    I know, the laggish behaviour is caused by sizeHint, because if I remove its implementation everything works just fine... Any idea, what I can do to improve the code, stopping it to be "laggish"?

    Appreciate any help!

    Ps: I tested it both under Qt 4.8.5 and Qt 5.1.1, same result.

    1 Reply Last reply
    0
    • A Offline
      A Offline
      Agroni
      wrote on last edited by
      #2

      You are recreating QTextDocument doc everytime sizeHint is called. It may be called a million times on just one refresh of a screen.

      I would recommend to ...

      1. keep doc outside sizeHint.
      2. call doc.setHtml(optionV4.text); only when content has changed.
      3. call #2 outside sizeHint
      4. call doc.setTextWidth(optionV4.rect.width()); also only when content has changed
      5. call #4 outside sizeHint
      6. you can keep the last line maybe with a little modification :)
        return QSize(m_doc.idealWidth(), m_doc.size().height());
      1 Reply Last reply
      0
      • A Offline
        A Offline
        aran
        wrote on last edited by
        #3

        That makes sense, thanks! No wonder it's slow.

        However, I can't figure out how to check if the content has changed. The problem is, that both functions are const, i.e. assigning anything from there to e.g. a global variable doesn't work:

        (header)
        QString txt;

        (paint/sizehint)
        txt = options.text

        -> doesn't compile:
        passing 'const QString' as 'this' argument of 'QString& QString::operator=(const QString&)' discards qualifiers

        But how else could I keep track of changes of the content?

        1 Reply Last reply
        0
        • A Offline
          A Offline
          aran
          wrote on last edited by
          #4

          Okay, I think I got it now, the (now deleted?) comment about the mutable keyword helped a lot.
          No I check for changes in content and/or changes in the optionV4.rect, and only if at least one of them changed then I recalculate the sizeHint. Here's the code I came up with:

          (header)
          @private:
          mutable QHash<QPair<int,int>, QString> txt;
          mutable QHash<QPair<int,int>, QSize> docSize;
          mutable QHash<QPair<int,int>, QRect> optionRect;@

          (source)
          @QSize RichTextDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const {

          QStyleOptionViewItemV4 optionV4 = option;
          initStyleOption(&optionV4, index);

          QPair<int,int> p;
          p.first = index.row();
          p.second = index.column();

          if(txt[p] != optionV4.text || optionRect[p] != optionV4.rect) {

          QTextDocument doc;
          doc.setHtml(optionV4.text);
          doc.setTextWidth(optionV4.rect.width());

          txt[p] = optionV4.text;

          docSize[p] = QSize(doc.idealWidth(),doc.size().height());
          optionRect[p] = optionV4.rect;

          }

          return docSize[p];

          }@

          I hope I haven't missed something important, but, as far as I can tell, that works quite well.

          Thanks a million to Agroni and the other person of the deleted comment!

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved