Results 1 to 5 of 5

Thread: QPainter::drawText() with word wrap

  1. #1
    Join Date
    Dec 2008
    Location
    Istanbul, TURKEY
    Posts
    537
    Thanks
    14
    Thanked 13 Times in 13 Posts
    Qt products
    Qt4
    Platforms
    Windows Android

    Default QPainter::drawText() with word wrap

    Hi,

    I have QListView which I display my item's(in the model) specific data on it. If the item's message data is too long I need to resize the drawText rectangle in order to fit the string to the given option rect. I looked at the forum and find some useful code but still having no success. I have still the following case;

    sample.jpg

    It seems like I couldn't get the text wrapped inside drawText method. Here is my delegate class code. Any help will be greatly appreciated.

    Qt Code:
    1. void ChatViewListItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    2. {
    3. QRect rect = option.rect;
    4. int textOffset = 5;
    5. QPalette pal = option.palette;
    6. QVariant variant = index.data(Qt::UserRole);
    7.  
    8. painter->save();
    9.  
    10. QString displayName;
    11. QDateTime dateTime;
    12. QString dateTimeInString;
    13. QString messageContent;
    14. QString direction;
    15. QString state;
    16.  
    17. if(variant.canConvert<ChatMessageHistoryItem>())
    18. {
    19. ChatMessageHistoryItem item = variant.value<ChatMessageHistoryItem>();
    20. displayName = ApplicationManager::getInstance()->getAddressBookManager()->findContactName((item.getDisplayName()));
    21. dateTime = item.getDateTime();
    22. dateTimeInString = dateTime.toString("dd/MM/yyyy hh:mm");
    23. direction = item.getDirection();
    24. state = item.getState();
    25. messageContent = qvariant_cast<QString>(index.data(ChatViewListModel::MessageContentRole));
    26.  
    27. if(item.getDirection().compare(HistoryItem::DIRECTION_INCOMING) == 0)
    28. {
    29. painter->setPen(QColor("#034567"));
    30. }
    31. else
    32. {
    33. if(ApplicationManager::getInstance()->getAddressBookManager()->getMyContact())
    34. {
    35. displayName = ApplicationManager::getInstance()->getAddressBookManager()->getMyContact()->getDisplayName();
    36. }
    37. painter->setPen(QColor("#B0171F"));
    38. //painter->setPen(QColor("#034567"));
    39. }
    40. }
    41.  
    42. /*
    43. if(!direction.isNull() &&
    44. !direction.isEmpty() &&
    45. direction.compare(HistoryItem::DIRECTION_OUTGOING) == 0)
    46. {
    47. painter->fillRect(option.rect, QColor("#F5F7FA"));
    48. }
    49. */
    50.  
    51. QFont defaultFont = QApplication::font();
    52. QFont nameFont(defaultFont);
    53. nameFont.setPixelSize(12);
    54. nameFont.setBold(true);
    55. QFontMetrics nameFontFontMetrics(nameFont);
    56. int textHeightInPixels = nameFontFontMetrics.height();
    57.  
    58. QFont dateTimeFont = QApplication::font();
    59. dateTimeFont.setPixelSize(9);
    60. QFontMetrics dateTimeFontMetrics(dateTimeFont);
    61. int dateTimeTextWidthInPixels = dateTimeFontMetrics.width(dateTimeInString);
    62.  
    63. QRect displayNameRect = nameFontFontMetrics.boundingRect(textOffset,
    64. rect.top() + 5,
    65. rect.width() - textOffset - dateTimeTextWidthInPixels - 5 - 10 , 0,
    66. Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap,
    67. displayName);
    68. painter->setFont(nameFont);
    69. painter->drawText(displayNameRect, Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap, displayName);
    70.  
    71. painter->setFont(dateTimeFont);
    72. painter->setPen(QColor(Qt::lightGray));
    73. painter->drawText(rect.x() + rect.width() - dateTimeTextWidthInPixels - 5, rect.y() + 15, dateTimeInString);
    74.  
    75. QFont messageFont = QApplication::font();
    76. messageFont.setPixelSize(11);
    77. QFontMetrics messageFontMetrics(messageContent);
    78. int messageTextHeightInPixels = messageFontMetrics.height();
    79.  
    80. QRect messageContentRect = messageFontMetrics.boundingRect(textOffset,
    81. rect.top() + textHeightInPixels + 8,
    82. rect.width() - textOffset - dateTimeTextWidthInPixels - 5 - 10 , 0,
    83. Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap,
    84. messageContent);
    85. painter->setFont(messageFont);
    86. painter->setPen(QColor("#363636"));
    87. painter->drawText(messageContentRect, Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap, messageContent);
    88.  
    89. QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
    90. QPixmap pixmapDeliveryStatus = icon.pixmap(12, 12);
    91.  
    92. if(!direction.isNull() &&
    93. !direction.isEmpty() &&
    94. direction.compare(HistoryItem::DIRECTION_OUTGOING) == 0)
    95. {
    96. if(state.compare(HistoryItem::STATE_SENT, Qt::CaseInsensitive) == 0)
    97. {
    98. pixmapDeliveryStatus = icon.pixmap(14, 14);
    99. }
    100.  
    101. painter->drawPixmap(rect.x() +rect.width() - pixmapDeliveryStatus.width() - 5, rect.y() + textHeightInPixels + 8 , pixmapDeliveryStatus);
    102.  
    103. if(state.compare(HistoryItem::STATE_DISPLAYED, Qt::CaseInsensitive) == 0)
    104. {
    105. painter->drawPixmap(rect.x() +rect.width() - pixmapDeliveryStatus.width() - 9, rect.y() + textHeightInPixels + 8 , pixmapDeliveryStatus);
    106. }
    107. }
    108.  
    109. painter->setPen(QColor("#E5E5E5"));
    110. painter->drawLine(textOffset, rect.y() + textHeightInPixels + messageTextHeightInPixels + 10, rect.width() - textOffset, rect.y() + textHeightInPixels + messageTextHeightInPixels + 10);
    111.  
    112. painter->restore();
    113. }
    114.  
    115. QSize ChatViewListItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    116. {
    117. int textOffset = 5;
    118. QRect rect = option.rect;
    119. QVariant variant = index.data(Qt::UserRole);
    120. QString displayName = "";
    121. QString messageContent = "";
    122. QString dateTimeInString = "";
    123. if(variant.canConvert<ChatMessageHistoryItem>())
    124. {
    125. ChatMessageHistoryItem item = variant.value<ChatMessageHistoryItem>();
    126. displayName = ApplicationManager::getInstance()->getAddressBookManager()->findContactName((item.getDisplayName()));
    127. dateTimeInString = item.getDateTime().toString("dd/MM/yyyy hh:mm");
    128. messageContent = qvariant_cast<QString>(index.data(ChatViewListModel::MessageContentRole));
    129. }
    130.  
    131. QFont dateTimeFont = QApplication::font();
    132. dateTimeFont.setPixelSize(9);
    133. QFontMetrics dateTimeFontMetrics(dateTimeFont);
    134. int dateTimeTextWidthInPixels = dateTimeFontMetrics.width(dateTimeInString);
    135.  
    136. QFont defaultFont = QApplication::font();
    137. QFont nameFont(defaultFont);
    138. nameFont.setPixelSize(12);
    139. nameFont.setBold(true);
    140. QFontMetrics nameFontFontMetrics(nameFont);
    141. int textHeightInPixels = nameFontFontMetrics.height();
    142.  
    143. int value = rect.width() - textOffset - dateTimeTextWidthInPixels - 5 - 10;
    144.  
    145. QRect displayNameRect = nameFontFontMetrics.boundingRect(0, 0,
    146. rect.width() - textOffset - dateTimeTextWidthInPixels - 5 - 10, 0,
    147. Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap,
    148. displayName);
    149.  
    150. QFont messageFont = QApplication::font();
    151. messageFont.setPixelSize(11);
    152. QFontMetrics messageFontMetrics(messageContent);
    153. int messageTextHeightInPixels = messageFontMetrics.height();
    154.  
    155. QRect messageContentRect = messageFontMetrics.boundingRect(0, 0,
    156. rect.width() - textOffset - dateTimeTextWidthInPixels - 5 - 10 , 0,
    157. Qt::AlignLeft|Qt::AlignTop|Qt::TextWordWrap,
    158. messageContent);
    159.  
    160. QSize sizeAdjusted(option.rect.width(), displayNameRect.height() + messageContentRect.height());
    161.  
    162. qDebug() << "total height: " << displayNameRect.height() + messageContentRect.height();
    163. // Keep the minimum height needed in mind.
    164. if(sizeAdjusted.height() < ITEM_HEIGHT)
    165. {
    166. sizeAdjusted.setHeight(ITEM_HEIGHT);
    167. }
    168.  
    169. //QSize orig = QItemDelegate::sizeHint(option, index);
    170. //return QSize(orig.width(), ITEM_HEIGHT);
    171. return sizeAdjusted;
    172. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawText() with word wrap

    From your screen shot it looks like you have a very long word, so word wrap can't break it.

    Have you tried Qt::TextWrapAnywhere?

    Cheers,
    _

  3. #3
    Join Date
    Dec 2008
    Location
    Istanbul, TURKEY
    Posts
    537
    Thanks
    14
    Thanked 13 Times in 13 Posts
    Qt products
    Qt4
    Platforms
    Windows Android

    Default Re: QPainter::drawText() with word wrap

    Yeah, just tried and it worked. Thanks for your advice.

    Now I'm facing a bit minor problem. Text is wrapped as expected but returned size's height is much bigger than the text wrapped. See the attached view. Any ideas for that?

    sample2.jpg

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawText() with word wrap

    The screenshot is extremely small, but I assume you mean that the item height is taller than what you expect.

    One thing you can try is to get the actually consumed bounding rect for the text drawing. The drawText() method has an option QRect pointer argument that, if present, will be set to the bounding rect the text actually needed when drawn.

    Qt Code:
    1. QRect usedRect;
    2. painter->drawText( itemRect, flags, text, &usedRect );
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  5. The following user says thank you to anda_skoa for this useful post:

    zgulser (18th December 2013)

  6. #5
    Join Date
    Dec 2008
    Location
    Istanbul, TURKEY
    Posts
    537
    Thanks
    14
    Thanked 13 Times in 13 Posts
    Qt products
    Qt4
    Platforms
    Windows Android

    Default Re: QPainter::drawText() with word wrap

    Hi,

    I didn't recognize the parameter that you suggest. I tried it but no luck. Thanks anyways.


    Added after 12 minutes:


    Oh I caught the error. I set message instead of font in the sizeHint(...). Problem solved.
    Last edited by zgulser; 18th December 2013 at 11:30.

Similar Threads

  1. Replies: 2
    Last Post: 9th April 2013, 06:26
  2. word wrap
    By deeee in forum Qt Programming
    Replies: 3
    Last Post: 26th May 2010, 19:55
  3. Long text and word wrap in QPainter
    By TomASS in forum Qt Programming
    Replies: 2
    Last Post: 11th December 2009, 11:50
  4. KTitleWidget & word wrap
    By miraks in forum KDE Forum
    Replies: 3
    Last Post: 29th March 2009, 23:24
  5. QListView word wrap
    By serega in forum Qt Programming
    Replies: 17
    Last Post: 30th August 2007, 03:13

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.