Results 1 to 20 of 34

Thread: Word wrap in QListView

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Word wrap in QListView

    Hi,
    have used the code of marcel creating a qtrewidget with word-wrap function and it works nice. The next step should be display html text instead of plain text like now. I have used the following code in overridden paint():

    Qt Code:
    1. painter->save();
    2. doc.setHtml(index.data().toString());
    3. QAbstractTextDocumentLayout::PaintContext context;
    4. doc.setPageSize(option.rect.size());
    5. painter->translate(option.rect.x(), option.rect.y());
    6. doc.documentLayout()->draw(painter, context);
    7. painter->restore();
    To copy to clipboard, switch view to plain text mode 

    ( instead of painter->drawText() ) but with no luck: the treeWidget is illegible.

    Any hint?

    Some code:
    delegate.cpp
    Qt Code:
    1. void delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex & index) const
    2. {
    3. painter->save();
    4. doc.setHtml(index.data().toString());
    5. QAbstractTextDocumentLayout::PaintContext context;
    6. doc.setPageSize(option.rect.size());
    7. painter->translate(option.rect.x(), option.rect.y());
    8. doc.documentLayout()->draw(painter, context);
    9. painter->restore();
    10. // painter->drawText(option.rect, Qt::AlignLeft | Qt::TextWordWrap, index.data().toString());
    11. }
    12.  
    13. QSize delegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
    14. {
    15. QTreeWidget *p = (QTreeWidget*)parent();
    16. QFontMetrics fm(p->font());
    17.  
    18. float rw = float(p->viewport()->size().width());
    19. float tw = fm.width(index.data().toString());
    20. float ratio = tw/rw;
    21. int lines = int(ratio) + 1;
    22. return QSize(rw,lines*fm.height());
    23. }
    To copy to clipboard, switch view to plain text mode 

    Thanks
    Giuseppe CalÃ

  2. #2
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Word wrap in QListView

    Hi,
    I'm planning use two different delegate to draw items so I choose QListWidget. For providing support to the two delegates I created a new class, named ListWidgetItemDelegate (like StarDelegate example in the manual). Now from the MainDialog I can decide which delegate using. All works fine. I then decided to modify one of the delegate for supporting the marcel's word-wrap solution:

    Qt Code:
    1. QSize SectionItem::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
    2. {
    3. QListWidget *p = (QListWidget*)parent();
    4. QString text = index.data().toString();
    5. QFontMetrics fm(p->font());
    6. float rw = float(p->viewport()->size().width());
    7. float tw = fm.width(text);
    8. float ratio = tw/rw;
    9. int lines = int(ratio) + 1;
    10. return QSize(rw,lines*fm.height());
    11. }
    To copy to clipboard, switch view to plain text mode 

    but i get an error during compiling because parent is not declared in the scope. Now from maindialog passing by ListWidgetItemDelegate to SectionItem I'm little lost and i don't know which row modify for passing the right parent.

    Here the code that have used hoping someone, read marcel, can help me:

    listwidgetitemdelegate.cpp
    Qt Code:
    1. #include "listwidgetitemdelegate.h"
    2. #include "headeritem.h"
    3. #include "sectionitem.h"
    4.  
    5. void ListWidgetItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    6. {
    7. if (qVariantCanConvert<HeaderItem>(index.data()))
    8. {
    9. HeaderItem headerItem = qVariantValue<HeaderItem>(index.data());
    10. headerItem.paint(painter, option, index);
    11. }
    12. else if (qVariantCanConvert<SectionItem>(index.data()))
    13. {
    14. SectionItem sectionItem = qVariantValue<SectionItem>(index.data());
    15. sectionItem.paint(painter, option, index);
    16. }
    17. else
    18. {
    19. QItemDelegate::paint(painter, option, index);
    20. }
    21. }
    22.  
    23. QSize ListWidgetItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    24. {
    25. if (qVariantCanConvert<SectionItem>(index.data())) {
    26. SectionItem sectionItem = qVariantValue<SectionItem>(index.data());
    27. return sectionItem.sizeHint(option, index);
    28. } else {
    29. return QItemDelegate::sizeHint(option, index);
    30. }
    31. }
    To copy to clipboard, switch view to plain text mode 

    sectionitem.cpp
    Qt Code:
    1. #include "sectionitem.h"
    2.  
    3. SectionItem::SectionItem(QString text)
    4. {
    5. itemText = text;
    6. }
    7.  
    8. SectionItem::~SectionItem()
    9. {
    10. }
    11.  
    12. void SectionItem::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex & index) const
    13. {
    14. painter->save();
    15. painter->setPen(QPen(Qt::darkGreen));
    16. painter->drawText(option.rect, Qt::AlignLeft | Qt::TextWordWrap, itemText);
    17. painter->restore();
    18. }
    19.  
    20. QSize SectionItem::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
    21. {
    22. QListWidget *p = (QListWidget*)parent();
    23. QFontMetrics fm(p->font());
    24.  
    25. float rw = float(p->viewport()->size().width());
    26. float tw = fm.width(itemText);
    27. float ratio = tw/rw;
    28. int lines = int(ratio) + 1;
    29. return QSize(rw,lines*fm.height());
    30. }
    To copy to clipboard, switch view to plain text mode 

    maindialog.cpp
    Qt Code:
    1. ...
    2. listWidget = new QListWidget;
    3. listWidget->setItemDelegate(new ListWidgetItemDelegate);
    4. listWidget->setAlternatingRowColors(true);
    5. listWidget->setResizeMode(QListWidget::Adjust);
    6.  
    7. list << "New Section"
    8. << "The <b>QListWidgetItem</b> class provides an item for use with the QListWidget item view class."
    9. << "The <b>QObject</b> class is the base class of all Qt objects."
    10. << "Qt's <b>drag and drop</b> infrastructure is fully supported by the model/view framework. Items in lists, tables, and trees can be dragged within the views, and data can be imported and exported as MIME-encoded data. ciao da giuseppe";
    11.  
    12. item1->setData(0, qVariantFromValue(HeaderItem(list.at(0))));
    13. listWidget->insertItem(0, item1);
    14.  
    15. for(int i = 1; i < list.size(); i++)
    16. {
    17. item->setData(0, qVariantFromValue(SectionItem(list.at(i))));
    18. listWidget->insertItem(i, item);
    19. }
    20. ...
    To copy to clipboard, switch view to plain text mode 

    Regards
    Giuseppe CalÃ

  3. #3
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: Word wrap in QListView

    In ListWidgetItemDelegate::sizeHint you can pass parent() to SectionItem::sizeHint(). All you have to do is to add another parameter to SectionItem's sizeHint method.
    SectionItem is not a QAbstractItemDelegate, isn't it?

    Regards

  4. #4
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Word wrap in QListView

    No marcel, SectionItem is not a QAbstractItemDelegate. Now I edit the code and then tell you the result.

    Thanks
    Giuseppe CalÃ

  5. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: Word wrap in QListView

    Yes. Just make sure you pass the parent of ListWidgetItemDelegate.

    Regards

  6. #6
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Word wrap in QListView

    I'm making some sort of mistake because i got errors during compiling; here the modifications:

    listwidgetitemdelegate.cpp
    Qt Code:
    1. ...
    2. return sectionItem.sizeHint(parent, option, index);
    3. ...
    To copy to clipboard, switch view to plain text mode 

    sectionitem.h
    Qt Code:
    1. ...
    2. QSize sizeHint(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
    3. ...
    To copy to clipboard, switch view to plain text mode 

    sectionitem.cpp
    Qt Code:
    1. QSize SectionItem::sizeHint(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
    2. {...}
    To copy to clipboard, switch view to plain text mode 

    For clearness here the code for the header files:
    listwidgetitemdelegate.h
    Qt Code:
    1. class ListWidgetItemDelegate : public QItemDelegate
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. ListWidgetItemDelegate(QWidget *parent = 0) : QItemDelegate(parent) {}
    7.  
    8. void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    9.  
    10. QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
    11. };
    To copy to clipboard, switch view to plain text mode 

    sectionitem.h
    Qt Code:
    1. class SectionItem
    2. {
    3. public:
    4.  
    5. SectionItem(QString text = "");
    6. ~SectionItem();
    7.  
    8. void paint(QPainter*, const QStyleOptionViewItem&, const QModelIndex&) const;
    9. QSize sizeHint(QObject *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
    10.  
    11. private:
    12. QString itemText;
    13. };
    14.  
    15. Q_DECLARE_METATYPE(SectionItem)
    To copy to clipboard, switch view to plain text mode 

    Bye
    Giuseppe CalÃ

  7. #7
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: Word wrap in QListView

    Who is parent? The one that you pass to SectionItem::sizeHint().
    It should be (QListWidget*)parent().

    And in maindialog.cpp, it should be:
    Qt Code:
    1. listWidget->setItemDelegate(new ListWidgetItemDelegate(listWidget));
    To copy to clipboard, switch view to plain text mode 

  8. The following user says thank you to marcel for this useful post:

    jiveaxe (1st September 2007)

  9. #8
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Word wrap in QListView

    Ok marcel, now works! Here the modifications I made:

    maindialog.cpp
    Qt Code:
    1. listWidget->setItemDelegate(new ListWidgetItemDelegate(listWidget));
    To copy to clipboard, switch view to plain text mode 

    listwidgetitemdelegate.cpp
    Qt Code:
    1. ...
    2. return sectionItem.sizeHint(parent(), option, index);
    3. ...
    To copy to clipboard, switch view to plain text mode 

    sectionitem.h
    Qt Code:
    1. QSize sizeHint(QObject *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
    To copy to clipboard, switch view to plain text mode 

    sectionitem.cpp
    Qt Code:
    1. QSize SectionItem::sizeHint(QObject *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
    2. {
    3. QListWidget *p = (QListWidget*)parent;
    4. ...
    5. }
    To copy to clipboard, switch view to plain text mode 

    Thanks a lot
    Giuseppe CalÃ

  10. #9
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Word wrap in QListView

    I would like rendering html text instead of plain text; changing SectionItem:aint like this:

    Qt Code:
    1. void SectionItem::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex & index) const
    2. {
    3. painter->save();
    4. doc.setHtml(itemText);
    5. QAbstractTextDocumentLayout::PaintContext context;
    6. doc.setPageSize(option.rect.size());
    7. painter->translate(option.rect.x(), option.rect.y());
    8. doc.documentLayout()->draw(painter, context);
    9. painter->restore();
    10. // painter->drawText(option.rect, Qt::AlignLeft | Qt::TextWordWrap, index.data().toString());
    11. }
    To copy to clipboard, switch view to plain text mode 

    It renders html text but the last row of each phrase (when wrapped) is always drawn in the following item and a blank row remains in own item (see the attached image for better explanation).

    Any hint?

    Cheers
    Attached Images Attached Images
    Giuseppe CalÃ

  11. #10
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Word wrap in QListView

    I have found a possible solution even if for some widths it renders not optimally. Attached are 2 images, one with correct draw and one with the unwanted behavior.

    Here the new code for SectionItem:aint

    Qt Code:
    1. void SectionItem::paint(QObject *parent, QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex & index) const
    2. {
    3. QListWidget *p = (QListWidget*)parent;
    4.  
    5. painter->save();
    6. doc.setHtml(itemText);
    7. QAbstractTextDocumentLayout::PaintContext context;
    8. doc.setPageSize(QSize(option.rect.size().width(), option.rect.size().height() + p->viewport()->size().height()));
    9. painter->translate(option.rect.x(), option.rect.y());
    10. doc.documentLayout()->draw(painter, context);
    11. painter->restore();
    12. }
    To copy to clipboard, switch view to plain text mode 

    Regards
    Attached Images Attached Images
    Giuseppe CalÃ

  12. #11
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: Word wrap in QListView

    It might have to do with the HTML itself. Do you have any <p> tags or any other tag that enforces spacings around it?

    Can you paste the html?

    BTW: don't tell me that you too are working on (yet another) IDE.

    Regards

  13. #12
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Word wrap in QListView

    There aren't <p> tags in the html, only <b> and </b>, but here the code:

    Qt Code:
    1. list << "New Section"
    2. << "The <b>QListWidgetItem</b> class provides an item for use with the QListWidget item view class. The <b>QListWidgetItem</b> class provides an item for use with the QListWidget item view class. The <b>QListWidgetItem</b> class provides an item for use with the QListWidget item view class."
    3. << "The <b>QObject</b> class is the base class of all Qt objects."
    4. << "Qt's <b>drag and drop</b> infrastructure is fully supported by the model/view framework. Items in lists, tables, and trees can be dragged within the views, and data can be imported and exported as MIME-encoded data.";
    To copy to clipboard, switch view to plain text mode 

    ...and not, I am not working on a new ide.

    Bye
    Giuseppe CalÃ

  14. #13
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: Word wrap in QListView

    Qt Code:
    1. void SectionItem::paint(QObject *parent, QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex & index) const
    2. {
    3. QListWidget *p = (QListWidget*)parent;
    4.  
    5. painter->save();
    6. doc.setHtml(itemText);
    7. doc.setTextWidth(option.rect.size().width());
    8. QAbstractTextDocumentLayout::PaintContext context;
    9. painter->translate(option.rect.x(), option.rect.y());
    10. doc.documentLayout()->draw(painter, context);
    11. painter->restore();
    12. }
    13.  
    14.  
    15. QSize SectionItem::sizeHint(QObject *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
    16. {
    17. QListWidget *p = (QListWidget*)parent;
    18. QFontMetrics fm(p->font());
    19.  
    20. float rw = float(p->viewport()->size().width());
    21. float tw = fm.width(itemText);
    22. float ratio = tw/rw;
    23. int lines = 0;
    24. if(ratio - int(ratio) < 0.1f)
    25. lines = int(ratio);
    26. else
    27. lines = int(ratio) + 1;
    28. return QSize(rw,lines*fm.height());
    29. }
    To copy to clipboard, switch view to plain text mode 

    Problem 1: don't give the height to the text document. you already set it with the size hint.

    Problem 2: ocassionaly, due to rounding errors, you got 1 extra line of text that remained empty( the +1 in the sizeHint).

    Regards

  15. The following 2 users say thank you to marcel for this useful post:

    jiveaxe (1st September 2007), liuyanghejerry (26th August 2010)

  16. #14
    Join Date
    Aug 2007
    Posts
    244
    Qt products
    Qt4
    Platforms
    Unix/X11
    Thanks
    42
    Thanked 8 Times in 8 Posts

    Default Re: Word wrap in QListView

    Thank for your tips, marcel, helpful as usual; I have corrected the code.

    Regards
    Giuseppe CalÃ

Similar Threads

  1. QListView word wrap
    By serega in forum Qt Programming
    Replies: 17
    Last Post: 30th August 2007, 04: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
  •  
Qt is a trademark of The Qt Company.