Results 1 to 5 of 5

Thread: QTreeWidgetItem - widget with layout collapsing

  1. #1
    Join Date
    Jul 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default QTreeWidgetItem - widget with layout collapsing

    Hello! I have troubles with creating userlist in my IM. Because I need to display some data in one Item. I decided to embed QFrame into widget, make layout and insert labels into that layout. Here is code of my function used to create item (pointer is returned, needed by userlist manager)

    Qt Code:
    1. QTreeWidgetItem* QTlenRosterBox::addRosterItem(QString name,
    2. QTlenPresence type,
    3. QString desc,
    4. QString jid,
    5. QPixmap pxAvatar,
    6. {
    7. QTreeWidgetItem* item = new QTreeWidgetItem(node);
    8. QFrame* frame = new QFrame(this);
    9. QHBoxLayout* hLayout = new QHBoxLayout(frame);
    10. hLayout->setAlignment(Qt::AlignTop);
    11. QVBoxLayout* vLayout = new QVBoxLayout();
    12. vLayout->setAlignment(Qt::AlignTop);
    13. QLabel* statusIcon = new QLabel(frame);
    14. statusIcon->setFixedSize(16,16);
    15. switch (type)
    16. {
    17. case Online:
    18. statusIcon->setPixmap(QPixmap(QString::fromUtf8(":/icons/icons/16x16/online.png")));
    19. break;
    20. case Chatty:
    21. statusIcon->setPixmap(QPixmap(QString::fromUtf8(":/icons/icons/16x16/chatty.png")));
    22. break;
    23. case Away:
    24. statusIcon->setPixmap(QPixmap(QString::fromUtf8(":/icons/icons/16x16/away.png")));
    25. break;
    26. case XA:
    27. statusIcon->setPixmap(QPixmap(QString::fromUtf8(":/icons/icons/16x16/xa.png")));
    28. break;
    29. case DND:
    30. statusIcon->setPixmap(QPixmap(QString::fromUtf8(":/icons/icons/16x16/dnd.png")));
    31. break;
    32. case Offline:
    33. statusIcon->setPixmap(QPixmap(QString::fromUtf8(":/icons/icons/16x16/offline.png")));
    34. break;
    35. }
    36.  
    37. hLayout->addWidget(statusIcon);
    38. hLayout->addLayout(vLayout);
    39. QLabel* nameLabel = new QLabel(name, frame);
    40. QFont nameFont;
    41. nameFont.setBold(true);
    42. nameLabel->setFont(nameFont);
    43. vLayout->addWidget(nameLabel);
    44. if (!desc.isEmpty() && settings->value("/roster/show_descriptions", false).toBool())
    45. {
    46. QLabel* descLabel = new QLabel(desc, frame);
    47. QFont descFont;
    48. descFont.setPointSize(7);
    49. descFont.setItalic(true);
    50. descLabel->setWordWrap(true);
    51. descLabel->setFont(descFont);
    52. vLayout->addWidget(descLabel);
    53. }
    54. //prowizorka
    55. if(settings->value("/roster/show_avatars", false).toBool())
    56. {
    57. QLabel* avatar = new QLabel();
    58. if(pxAvatar.isNull())
    59. avatar->setPixmap(QPixmap(QString::fromUtf8(":/icons/icons/64x64/default_av.png")));
    60. else
    61. avatar->setPixmap(pxAvatar);
    62. avatar->setAlignment(Qt::AlignRight);
    63. hLayout->addWidget(avatar);
    64. }
    65. frame->setLayout(hLayout);
    66. setItemWidget(item, 0, frame);
    67. return item;
    68. }
    To copy to clipboard, switch view to plain text mode 

    and here is roster with only one item visible and with two visible; height is calculated properly, but layout is collapsed.

    how to fix that in best way?
    thanks in advance.
    Attached Images Attached Images
    Last edited by enkidu; 25th July 2009 at 19:53. Reason: user request

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTreeWidgetItem - widget with layout collapsing

    The best way is not to embed widgets but use delegates or at least report a proper size hint from the items.

    And please don't link images from 3-rd party sites, they tend to vanish over time making the thread useless. Attach images to your post instead.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jul 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTreeWidgetItem - widget with layout collapsing

    so I should try with QTreeView and QItemDelegate? I wanted to avoid that.

    Images are located on my server, so wont disappear without my knowledge

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTreeWidgetItem - widget with layout collapsing

    Quote Originally Posted by enkidu View Post
    so I should try with QTreeView and QItemDelegate? I wanted to avoid that.
    You can keep using QTreeWidget but you should implement your own item delegate.

    Images are located on my server, so wont disappear without my knowledge
    But they will disappear without my knowledge. I don't care if you remove them willingly or not, it's a fact that if they disappear, others won't benefit from this thread.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Jul 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTreeWidgetItem - widget with layout collapsing

    After making some other task I decided to reimplement item delegate. I modified StarDelegate example and finally got this:
    qtlenrosteritemdelegate.hpp
    Qt Code:
    1. #ifndef QTLENROSTERITEMDELEGATE_HPP
    2. #define QTLENROSTERITEMDELEGATE_HPP
    3. #include <QtGui>
    4. #include "qtlenrosteritem.hpp"
    5. class QTlenRosterItemDelegate: public QStyledItemDelegate
    6. {
    7. Q_OBJECT
    8. public:
    9. QTlenRosterItemDelegate(QWidget *parent = 0) : QStyledItemDelegate(parent) {}
    10. void paint(QPainter *painter, const QStyleOptionViewItem &option,
    11. const QModelIndex &index) const;
    12. QSize sizeHint(const QStyleOptionViewItem &option,
    13. const QModelIndex &index) const;
    14.  
    15. };
    16.  
    17. #endif // QTLENROSTERITEMDELEGATE_HPP
    To copy to clipboard, switch view to plain text mode 
    qtlenrosteritemdelegate.cpp
    Qt Code:
    1. void QTlenRosterItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
    2. const QModelIndex &index) const
    3. {
    4. if (qVariantCanConvert<QTlenRosterItem>(index.data())) {
    5. QTlenRosterItem rosterItem = qVariantValue<QTlenRosterItem>(index.data());
    6. bool checked = false;
    7. if (option.state & QStyle::State_Selected)
    8. {
    9. painter->fillRect(option.rect, option.palette.highlight());
    10. checked = true;
    11. }
    12. rosterItem.setHeight(rosterItem.paint(painter, option.rect, option.palette, checked));
    13. } else {
    14. QStyledItemDelegate::paint(painter, option, index);
    15. }
    16. }
    17.  
    18. QSize QTlenRosterItemDelegate::sizeHint(const QStyleOptionViewItem &option,
    19. const QModelIndex &index) const
    20. {
    21. if (qVariantCanConvert<QTlenRosterItem>(index.data())) {
    22.  
    23. QTlenRosterItem rosterItem = qVariantValue<QTlenRosterItem>(index.data());
    24. return rosterItem.sizeHint(option);
    25. } else {
    26. return QStyledItemDelegate::sizeHint(option, index);
    27. }
    28. }
    To copy to clipboard, switch view to plain text mode 
    qtlenrosteritem.hpp
    Qt Code:
    1. #ifndef QTLENROSTERITEM_HPP
    2. #define QTLENROSTERITEM_HPP
    3. #include "defines.h"
    4. #include <QtGui>
    5. class QTlenRosterItem
    6. {
    7. public:
    8. QTlenRosterItem(QString name = "", QTlenPresence type = Offline, QString desc="", QString jid="", QPixmap pxAvatar=QPixmap());
    9. int paint(QPainter *painter, const QRect &rect,
    10. const QPalette &palette, bool checked) const;
    11. QSize sizeHint(const QStyleOptionViewItem &option) const;
    12. int height;
    13. void setHeight(int);
    14. private:
    15. QString name;
    16. QPixmap presence;
    17. QString desc;
    18. QString jid;
    19. QPixmap avatar;
    20. };
    21. Q_DECLARE_METATYPE(QTlenRosterItem)
    22. #endif // QTLENROSTERITEM_HPP
    To copy to clipboard, switch view to plain text mode 
    qtlenrosteritem.cpp
    Qt Code:
    1. #include "qtlenrosteritem.hpp"
    2.  
    3. QTlenRosterItem::QTlenRosterItem(QString name, QTlenPresence type, QString desc, QString jid, QPixmap pxAvatar)
    4. {
    5. this->name = name;
    6. this->desc = desc;
    7. this->jid = jid;
    8. this->avatar = pxAvatar;
    9. height = 68;
    10. switch (type)
    11. {
    12. case Online:
    13. presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/online.png"));
    14. break;
    15. case Chatty:
    16. presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/chatty.png"));
    17. break;
    18. case Away:
    19. presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/away.png"));
    20. break;
    21. case XA:
    22. presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/xa.png"));
    23. break;
    24. case DND:
    25. presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/dnd.png"));
    26. break;
    27. case Offline:
    28. presence=QPixmap(QString::fromUtf8(":/icons/icons/16x16/offline.png"));
    29. break;
    30. }
    31. }
    32.  
    33. int QTlenRosterItem::paint(QPainter *painter, const QRect &rect, const QPalette &palette, bool checked) const
    34. {
    35. painter->save();
    36. painter->setRenderHint(QPainter::Antialiasing, true);
    37. if (checked) painter->setBrush(palette.highlightedText());
    38. else
    39. painter->setBrush(palette.foreground());
    40. //name
    41. QRect nameRect;
    42. nameRect.setLeft(rect.left()+20);
    43. nameRect.setRight(rect.right()-68);
    44. nameRect.setTop(rect.top()+2);
    45. nameRect.setBottom(rect.bottom()-2);
    46. QRect *nameBR = new QRect;
    47. QFont nameFont;
    48. nameFont.setBold(true);
    49. painter->setFont(nameFont);
    50. painter->drawText(nameRect, (int)(Qt::AlignLeft | Qt::TextWordWrap), name, nameBR);
    51. //jid
    52. QRect jidRect;
    53. jidRect.setLeft(rect.left()+20);
    54. jidRect.setRight(rect.right()-68);
    55. jidRect.setTop(nameBR->bottom()+2);
    56. jidRect.setBottom(nameBR->bottom()+18);
    57. QRect *jidBR = new QRect;
    58. nameFont.setBold(false);
    59. painter->setFont(nameFont);
    60. painter->drawText(jidRect, (int)(Qt::AlignLeft | Qt::TextWordWrap), jid, jidBR);
    61. //desc
    62. QRect descRect;
    63. descRect.setLeft(rect.left()+20);
    64. descRect.setRight(rect.right()-68);
    65. descRect.setTop(jidBR->bottom()+2);
    66. descRect.setBottom(rect.bottom()-2);
    67. QRect *descBR = new QRect;
    68. QFont descFont;
    69. descFont.setPointSize(7);
    70. descFont.setItalic(true);
    71. painter->setFont(descFont);
    72. painter->drawText(descRect, (int)(Qt::AlignLeft | Qt::TextWordWrap), desc, descBR);
    73. int textHeight = nameBR->height() + jidBR->height() + descBR->height()+8;
    74. int theight;
    75. if (textHeight > 68)
    76. theight = textHeight;
    77. else
    78. theight = 68;
    79. //setHeight(68);
    80. painter->drawPixmap(rect.left()+2, rect.top()-8+rect.height()/2,16, 16, presence);
    81. painter->drawPixmap(rect.right()-66, rect.top()+2, 64, 64, avatar);
    82. painter->restore();
    83. return theight;
    84. }
    85.  
    86. QSize QTlenRosterItem::sizeHint(const QStyleOptionViewItem &option) const
    87. {
    88. qDebug(QByteArray::number(option.rect.right()));
    89. QFont descFont;
    90. descFont.setPointSize(7);
    91. descFont.setItalic(true);
    92. QFontMetrics fm(descFont);
    93. QRect rect = fm.boundingRect(0,0,80,160, (int)(Qt::AlignLeft | Qt::TextWordWrap), desc);
    94. int h = rect.height();
    95. if ((h + 30) < 68)
    96. return QSize(160, 68);
    97. return QSize(160, h+30);
    98. }
    99.  
    100. void QTlenRosterItem::setHeight(int h)
    101. {
    102. height = h;
    103. }
    To copy to clipboard, switch view to plain text mode 

    What I found, that in calculating SizeHint option.rect is not providing width, so I cannot calculate width of text blocks properly. This results in improper calculated height (only few pixels fortunately). Other thing, that is strange for me (maybe I'm misunderstanding docs) is that painter->setBrush(palette.highlightedText()); doesn't work as expected - text is still black (as if I used painter->setBrush(palette.foreground()) while for selected items should be white (or other colour derived from style). Any ideas? Thanks in advance.

Similar Threads

  1. changing layout of a widget
    By mikro in forum Qt Programming
    Replies: 10
    Last Post: 4th August 2009, 20:21
  2. hiding a widget without rearrange layout
    By mastupristi in forum Newbie
    Replies: 1
    Last Post: 6th July 2009, 17:20
  3. Replies: 1
    Last Post: 14th May 2009, 22:00
  4. Resize widget force layout resizing
    By ^NyAw^ in forum Qt Programming
    Replies: 17
    Last Post: 11th February 2009, 11:27
  5. resizing events of a custom widget in a layout
    By Rooster in forum Qt Programming
    Replies: 7
    Last Post: 16th February 2008, 10:52

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.