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. How to calculate line while wrapping text in QLIstview
Qt 6.11 is out! See what's new in the release blog

How to calculate line while wrapping text in QLIstview

Scheduled Pinned Locked Moved General and Desktop
6 Posts 2 Posters 3.6k 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.
  • P Offline
    P Offline
    prankur.sarbhai
    wrote on last edited by
    #1

    Hi,

    I am working on messaging application. I have a delegate which arrange text in different rect to draw text. I have to show - Name, date and time, Subject, Message , message status Icon. It doesnt work well (ie it create extra lines) in case if word is long . There is some problem in calculating in sizeHint but i tried different scenarios and couldnt make it working . for long text there are always extra lines coming in QLIstView .
    Please check the link below :
    !http://tinypic.com/r/34dt1de/5(Message shown in QListView)!

    Here's the code for this:
    @
    QSize ConversationViewItemDelegate::sizeHint(const QStyleOptionViewItem& , const QModelIndex& index) const
    {
    QString str = index.data().toString();

    QListView *view = (QListView*)parent();
    QFontMetrics fontMetrics(view->font());
    
    QStringList words = str.split(QChar(' '));
    words.removeAll("\n");
    QStringList lines = str.split(QChar('\n'));
    int noOfLines = lines.size();
    
    QRectF boundingRect = fontMetrics.boundingRect(str);
    int width = view->viewport()->width() -35;
    int height = boundingRect.height();
    int times = 0;
    while (words.size() > 0)
    {
        times++;
        qreal lineWidth = 0;
        bool enoughSpace = true;
        do
        {
            QString word = words.first();
            qreal wordWidth = fontMetrics.width(word);
            wordWidth = wordWidth + lineWidth;
            lineWidth = 0;
            if(wordWidth > width)
            {
                times++;
                while(wordWidth > width )
                {
                    times++;
                    wordWidth -= width;
                }
                lineWidth += wordWidth;
                lineWidth += fontMetrics.width(QChar(' '));
                words.removeFirst();
            }
            else if (wordWidth < width)
            {
                lineWidth += wordWidth;
                lineWidth += fontMetrics.width(QChar(' '));
                words.removeFirst();
            }
            else
                enoughSpace = false;
        }
        while (enoughSpace && words.size() > 0);
    }
    
    height = height * times  + (noOfLines + 3)* boundingRect.height() - times;
    QSize sizeOfSubjectField = QSize();
    if (!index.model()->data(index, ConversationViewMsgSubjectRole).toString().isEmpty())
    {
     QString subject = "Subject: " +  index.model()->data(index, ConversationViewMsgSubjectRole).toString();
     sizeHintforSubject(subject);
    }
    else
    {
        height = height - boundingRect.height();
    }
    
    height += sizeOfSubjectField.height();
    return QSize(width,  height);
    

    }

    QSize ConversationViewItemDelegate::sizeHintforSubject(QString str) const
    {
    QListView p = (QListView)parent();
    QString text = str;
    QFontMetrics fm(p->font());

    float rw = float(p->viewport()->size().width());
    float tw = fm.width(text);
    float ratio = tw/rw;
    int lines = int(ratio) + 1;
    return QSize(rw,lines*fm.height());
    

    }

    @

    1 Reply Last reply
    0
    • P Offline
      P Offline
      prankur.sarbhai
      wrote on last edited by
      #2

      the paint function code is as follows:
      @void ConversationViewItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex & index) const
      {

      QString displayName = index.model()->data(index, ConversationViewDisplayNameRole).toString();
      QString dateTime = index.model()->data(index, ConversationViewDateTimeRole).toString();
      bool messageStatus = index.model()->data(index, ConversationViewMsgReadRole).toBool();
      QString textMessage = index.model()->data(index, ConversationViewMessageRole).toString();
      
      QString subject = QString();
      
      if (!index.model()->data(index, ConversationViewMsgSubjectRole).toString().isEmpty())
      {
       subject = "Subject: " +  index.model()->data(index, ConversationViewMsgSubjectRole).toString();
      }
      
      QIcon messageStatusIcon =  index.model()->data(index, ConversationViewMsgStatusIcon).value<QIcon>();
      QPixmap pMessageStatusPixmap = messageStatusIcon.pixmap(option.decorationSize);
      
      QRect messageRect = option.rect;
      QRect dateTimeRect = option.rect;
      QRect boundaryRect = option.rect;
      QRect displayNameRect = option.rect;
      QRect sendMessageIconRect = option.rect;
      QRect subjectRect = option.rect;
      
      dateTimeRect.setTop(dateTimeRect.top()+5);
      dateTimeRect.setBottom(dateTimeRect.top()+15);
      dateTimeRect.setLeft(dateTimeRect.right()- 110);
      dateTimeRect.setRight(dateTimeRect.right()-5);
      
      displayNameRect.setTop(displayNameRect.top()+5);
      displayNameRect.setBottom(displayNameRect.top()+15);
      displayNameRect.setLeft(displayNameRect.left()+5);
      displayNameRect.setRight(displayNameRect.right()-120);
      
      boundaryRect.setRight(boundaryRect.right() - 2);
      boundaryRect.setLeft(boundaryRect.left() + 2);
      
      if(!index.model()->data(index, ConversationViewMsgSubjectRole).toString().isEmpty())
      {
          QSize a  = sizeHintforSubject(subject);
          subjectRect.setTop(dateTimeRect.bottom() + 2);
          subjectRect.setLeft(subjectRect.left() + 10);
          subjectRect.setRight(subjectRect.right() - 35);
          subjectRect.setBottom(subjectRect.top() + a.height());
      
          messageRect.setTop(subjectRect.bottom()+ 5);
          messageRect.setRight(messageRect.right() - 5);
      }
      else
      {
          messageRect.setTop(dateTimeRect.bottom()+10);
          messageRect.setRight(messageRect.right() - 25);
      }
      messageRect.setLeft(messageRect.left() + 10);
      messageRect.setBottom(messageRect.bottom() - 5);
      
      sendMessageIconRect.setTop(dateTimeRect.bottom()+2 );
      sendMessageIconRect.setRight(sendMessageIconRect.right()-5);
      sendMessageIconRect.setLeft(sendMessageIconRect.right()- 20);
      sendMessageIconRect.setBottom(dateTimeRect.bottom()+20);
      
      QFont boldFont = QApplication::font();
      boldFont.setBold(true);
      QFont normalFont = QApplication::font();
      QFont italicFont = QApplication::font();
      italicFont.setItalic(true);
      
      //Change color in message is UNREAD
      if(!messageStatus)
      {
         painter->fillRect(boundaryRect, "#C0C0C0");
      }
      //Set selected Message item color
      if (option.state & QStyle::State_Selected)
           painter->fillRect(boundaryRect, "#C8E0FD");
      
      painter->save();
      painter->drawRoundedRect(boundaryRect, 3, 3);
      painter->drawText(dateTimeRect, Qt::AlignLeft  , dateTime);
      painter->drawPixmap(sendMessageIconRect, pMessageStatusPixmap);
      
      QTextOption opt ;
      opt.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
      painter->drawText(messageRect,textMessage, opt );
      
      painter->setFont(italicFont);
      painter->drawText(subjectRect,subject, opt );
      painter->setFont(boldFont);
      painter->drawText(displayNameRect, Qt::AlignLeft  , displayName);
      
      
      painter->restore();
      

      }@

      some how the pic didnt come . the link for it is http://tinypic.com/r/34dt1de/5

      1 Reply Last reply
      0
      • P Offline
        P Offline
        prankur.sarbhai
        wrote on last edited by
        #3

        Any suggestions ????

        1 Reply Last reply
        0
        • raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          what is exactly the problem?!
          the image you've posted seems ok?

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • P Offline
            P Offline
            prankur.sarbhai
            wrote on last edited by
            #5

            Hi Raven,

            Thanks for the reply. Actually I am trying to make a chat view using QLIstview to show previous msges. The problem which i am facing is that where the text is very long there are extra space (extra number of lines from size hint) in list view item. i checked the previous post and wrote the size hint , it works only for small texts. If i show long text having long words then extra spaces comes in list view item. I am using WrapAtWordBoundaryOrAnywhere .

            Regards,
            Prankur

            1 Reply Last reply
            0
            • raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by
              #6

              maybe your text contains "\n" which cause the extra line breaks?

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              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