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. Text in a cell with more than one color
QtWS25 Last Chance

Text in a cell with more than one color

Scheduled Pinned Locked Moved General and Desktop
8 Posts 2 Posters 1.9k Views
  • 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.
  • C Offline
    C Offline
    cimer84
    wrote on last edited by
    #1

    I want to show a rich text (<b>18R - <7b> <red> 18L </red>) in a cell of a table view. Which is the best way to do this?

    Do you have some example about this?

    Thank you,

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by Chris Kawa
      #2

      You can create a custom QStyledItemDelegate and override the paint(...) method. Inside it you can use QTextDocument to format and paint the content however you need.

      1 Reply Last reply
      0
      • C Offline
        C Offline
        cimer84
        wrote on last edited by
        #3

        Thank you. I have already done it but I haven't seen any letter.
        I show my code:

        • void LrgRunwayCloserStyleItemDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
          {
          if((index.row() == 3) || ((index.row() == 4)))
          {
          painter->save();
          const QString runways = index.model()->data(index, Qt::DisplayRole ).toString();
          // Use any qt-supported html tags
          const QString html = QString( "<html style='color:#ff0000;'>%1</html>" ).arg( runways );
          QTextDocument doc;
          doc.setHtml( html );
          QRectF rc( option.rect );
          doc.drawContents( painter, rc );
          painter->restore();
          }
          else
          {
          QStyledItemDelegate::paint(painter, option, index);
          }
        1 Reply Last reply
        0
        • Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Yeah, it's a little counterintuitive, but the document is painted in the painter coords, not the clipping rectangle coords. To be more specific - no matter what the clipping rectangle is the document will paint starting in the upper left corner of the table (not the cell) and then be clipped to the cell rectangle.
          So to fix this you need to shift the painter coords and the clip rectangle coords to match these of the text document:

          ...
          doc.setHtml( html );
          painter->translate(option.rect.topLeft());
          doc.drawContents( painter, option.rect.translated(-option.rect.topLeft()) );
          painter->restore();
          ...
          

          Btw. you don't have to go through the model to get data. You can get it directly from the index:

          const QString runways = index.data(Qt::DisplayRole).toString();
          
          C 1 Reply Last reply
          0
          • Chris KawaC Chris Kawa

            Yeah, it's a little counterintuitive, but the document is painted in the painter coords, not the clipping rectangle coords. To be more specific - no matter what the clipping rectangle is the document will paint starting in the upper left corner of the table (not the cell) and then be clipped to the cell rectangle.
            So to fix this you need to shift the painter coords and the clip rectangle coords to match these of the text document:

            ...
            doc.setHtml( html );
            painter->translate(option.rect.topLeft());
            doc.drawContents( painter, option.rect.translated(-option.rect.topLeft()) );
            painter->restore();
            ...
            

            Btw. you don't have to go through the model to get data. You can get it directly from the index:

            const QString runways = index.data(Qt::DisplayRole).toString();
            
            C Offline
            C Offline
            cimer84
            wrote on last edited by
            #5

            @Chris-Kawa Ok thank you very much, I solve the problem, but I have another problem because I don't get to put the text center in the cell, is this possible?
            Instead of QDocumnet, is It possible to paint a QLabel? How?

            Thank You.

            1 Reply Last reply
            0
            • C Offline
              C Offline
              cimer84
              wrote on last edited by cimer84
              #6

              I put this code to QLabel but paint nothing


              • QLabel text(QString("<font color='red'><center><b>%1</b></center></font>").arg(options.text));
                text.setAlignment(Qt::AlignCenter);
                text.adjustSize();
                options.text = "";
                options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options,
                painter);
                painter->translate(options.rect.left(), options.rect.top());
                QPoint render_at( option.rect.left(), option.rect.top() );
                text.render( painter, render_at );******
              1 Reply Last reply
              0
              • Chris KawaC Offline
                Chris KawaC Offline
                Chris Kawa
                Lifetime Qt Champion
                wrote on last edited by Chris Kawa
                #7

                Sorry but this code makes little sense and creating a label to paint some text seems like an overkill.

                Here is an example that will center your text both horizontally and vertically

                void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                {
                    QRect clipRect(0,0,option.rect.width(), option.rect.height());
                
                    auto text = index.data(Qt::DisplayRole).toString();
                    auto html = QString("<p align=center style='color:#ff0000;'>%1</p>").arg(text);
                    
                    QTextDocument doc;
                    doc.setTextWidth(clipRect.width());
                    doc.setHtml(html);
                    auto docHeight =  doc.documentLayout()->documentSize().height();
                    auto vOffset = (clipRect.height() - docHeight) / 2;
                    
                    painter->save();
                    painter->translate(option.rect.left(), option.rect.top() + vOffset);
                    doc.drawContents(painter, clipRect);
                    painter->restore();
                }
                
                C 1 Reply Last reply
                0
                • Chris KawaC Chris Kawa

                  Sorry but this code makes little sense and creating a label to paint some text seems like an overkill.

                  Here is an example that will center your text both horizontally and vertically

                  void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                  {
                      QRect clipRect(0,0,option.rect.width(), option.rect.height());
                  
                      auto text = index.data(Qt::DisplayRole).toString();
                      auto html = QString("<p align=center style='color:#ff0000;'>%1</p>").arg(text);
                      
                      QTextDocument doc;
                      doc.setTextWidth(clipRect.width());
                      doc.setHtml(html);
                      auto docHeight =  doc.documentLayout()->documentSize().height();
                      auto vOffset = (clipRect.height() - docHeight) / 2;
                      
                      painter->save();
                      painter->translate(option.rect.left(), option.rect.top() + vOffset);
                      doc.drawContents(painter, clipRect);
                      painter->restore();
                  }
                  
                  C Offline
                  C Offline
                  cimer84
                  wrote on last edited by
                  #8

                  @Chris-Kawa Thank ypu very much for all, the solution is perfect.

                  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