Results 1 to 17 of 17

Thread: Model View - Delegate - setIndexWidget

  1. #1
    Join Date
    Mar 2008
    Posts
    29
    Thanks
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Model View - Delegate - setIndexWidget

    Hi,
    I tried to use the setIndexWidget() function in my MV GUI Qt Code.
    I just want to have a simple composed widget in my subclass instance of QTableView, an widget inside an table cell.
    Do you have any ideas or better code examples, how to use this function in the right way ? Trolltechs API docu does not explain, how to use this function in Qt's Model-View architecture. As is read before, the best way would be to use this in the delagate (with some dirty tricks), here you find some threads too, which describe my problem best:

    http://lists.trolltech.com/qt-intere...ad00097-0.html

    http://lists.trolltech.com/qt-intere...ad00550-0.html

    Kind regards,
    Alex

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Model View - Delegate - setIndexWidget

    Index widgets are not actually part of the MVC concept but they are additional widgets laid on top of items in the view. They are expensive to maintain and one should avoid them. What kind of widgets would you like to put there?
    J-P Nurmi

  3. #3
    Join Date
    Mar 2008
    Posts
    29
    Thanks
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Model View - Delegate - setIndexWidget

    I want to provide widgets in table cells, which consist of some text labels, some icons and an text edit field(date field), perhaps similar to the graphical interface of outlook calender...
    Can you help me how to proceed ?

  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: Model View - Delegate - setIndexWidget

    As for icons and text the default delegate should handle it fine. As for text edit fields - you'll be only editing one field at a time, so a slightly modified delegate returning a QTextEdit instance as the editor should be enough.

  5. #5
    Join Date
    Mar 2008
    Posts
    29
    Thanks
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Model View - Delegate - setIndexWidget

    Do you mean, I have to use the different roles in my custom model to let the default delegate render the cells content ?
    I tried to do so, but what made me first think of to try an different way, was, that with the decoration role I only could render one icon.
    I am also not sure, would it be possible to have drag and drop support, if I implement the cells content in this way ?

  6. #6
    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: Model View - Delegate - setIndexWidget

    Quote Originally Posted by starcontrol View Post
    Do you mean, I have to use the different roles in my custom model to let the default delegate render the cells content ?
    Yes, that's correct.

    I tried to do so, but what made me first think of to try an different way, was, that with the decoration role I only could render one icon.
    If you want something non-standard, use a custom delegate. You'll be able to render whatever you want depending on the data contained in an item.

    I am also not sure, would it be possible to have drag and drop support, if I implement the cells content in this way ?
    Yes, itemviews support d&d.

  7. #7
    Join Date
    Mar 2008
    Posts
    29
    Thanks
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Model View - Delegate - setIndexWidget

    So I have to implement the delegates paint() function to render my widget ?
    Do I have to paint my icons, text labels, editor fields ? There must be an way, instead "manually painting" the widgets, or ?

    A second wish:
    I have to create spans inside my table view, these spans will have to contain what I described before. The QTableView has an method setSpan(), but how can I check in my custom view from my custom model, where it has to paint the spans?

  8. #8
    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: Model View - Delegate - setIndexWidget

    Quote Originally Posted by starcontrol View Post
    So I have to implement the delegates paint() function to render my widget ?
    Not widget, but item - yes.

    Do I have to paint my icons, text labels, editor fields ?
    You only paint the inactive state. In the editing state the delegate returns a real widget.

    There must be an way, instead "manually painting" the widgets, or ?
    I think you have to define what you mean by "widget". Icon is not a widget. Text is not a widget. So, what is a widget according to your definition?

    I have to create spans inside my table view, these spans will have to contain what I described before. The QTableView has an method setSpan(), but how can I check in my custom view from my custom model, where it has to paint the spans?
    Why should the model care about the span? It's just a set of data.

  9. #9
    Join Date
    Mar 2008
    Posts
    29
    Thanks
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Model View - Delegate - setIndexWidget

    I think "manually painting" the items may not be the succeeding way. If I'll use the delegates paint method, I have a simple bitmap, which is rendered inside the table view cell (in my case, inside the span). If the span will be very long, because of an longer event (calender event) the bitmap will be strechted and the text will be rendered not clean, you understand what I mean ?
    The second problem is, the item will also have to contain an "active text edit field (date edit field for editing the event)" in the inactive state, how will this be possible with an rendered bitmap ?

    Kind regards,
    Alex

  10. #10
    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: Model View - Delegate - setIndexWidget

    Quote Originally Posted by starcontrol View Post
    If the span will be very long, because of an longer event (calender event) the bitmap will be strechted and the text will be rendered not clean, you understand what I mean ?
    The model doesn't care. It doesn't have a concept of width or height. The delegate handles all that and it is given the rectangle that needs to be painted.

    The second problem is, the item will also have to contain an "active text edit field (date edit field for editing the event)" in the inactive state, how will this be possible with an rendered bitmap ?
    Render the date as text and react on clicking the cell - activate the editor and let the user edit the date. You don't need the spinbox to be active all the time. You can even render the looks of the box if you really need to.

  11. #11
    Join Date
    Mar 2008
    Posts
    29
    Thanks
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Model View - Delegate - setIndexWidget

    Ok, I tried your suggestion..., but nothing is displayed in my table cells, do you know, what I am doing wrong ? How do I have to implement the sizeHint() function ?
    Qt Code:
    1. void SchulungsplanDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex &index)
    2. {
    3. painter->save();
    4.  
    5. if (option.state & QStyle::State_Active)
    6. painter->fillRect(option.rect, option.palette.highlight());
    7.  
    8. // gets the cells size and draws the text inside
    9. QRect myRect = QRect(option.rect.topLeft(), option.rect.bottomRight()) ;
    10. painter->drawText(myRect, Qt::AlignCenter, "test");
    11.  
    12. painter->restore();
    13. }
    14.  
    15. /*
    16. QSize sizeHint(const QStyleOptionViewItem &option,
    17.   const QModelIndex &index ) const
    18. {
    19. // ????????????
    20. }
    To copy to clipboard, switch view to plain text mode 

  12. #12
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Model View - Delegate - setIndexWidget

    The signature doesn't match. QAbstractItemDelegate::paint() is a const method. So in fact you're not reimplementing but shadowing the function.
    J-P Nurmi

  13. #13
    Join Date
    Mar 2008
    Posts
    29
    Thanks
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Model View - Delegate - setIndexWidget

    ok, thanks a lot ! ;-)
    Now it paints right... My second approach is, to paint an widget inside the table cell by grabbing the widget to an pixmap. This experiment seems to function, but the widget is VERY small inside the cell and you can only see the picture, if you resize the cell to a very, very large cell. I don't know why. The delegates painter got the right size of the cell.
    painter->drawPixmap(option.rect, courseItem);
    Do you know what I have to do ?

    Qt Code:
    1. void SchulungsplanDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex &index) const
    2. {
    3. if (index.column() == 3 && index.row() == 2)
    4. {
    5. painter->save();
    6.  
    7. if (option.state & QStyle::State_Active)
    8. painter->fillRect(option.rect, QBrush(QColor(Qt::darkGreen), Qt::SolidPattern));
    9. painter->setPen(QColor(Qt::white));
    10. painter->drawText(option.rect, Qt::AlignCenter, " 060505K1 8 von 01.01.2008 bis 10.01.2008 ");
    11.  
    12. // painter->drawPixmap(option.rect, QPixmap("arrowOpen.png"));
    13. painter->restore();
    14. }
    15.  
    16. if (index.column() == 1 && index.row() == 1)
    17. {
    18. painter->save();
    19.  
    20. QLabel* courseLabel = new QLabel("Hallo Welt");
    21. QPixmap courseItem = QPixmap::grabWidget(courseLabel);
    22. painter->drawPixmap(option.rect, courseItem);
    23.  
    24. painter->restore();
    25. }
    26. }
    To copy to clipboard, switch view to plain text mode 

  14. #14
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Model View - Delegate - setIndexWidget

    You might not want to allocate a QLabel like that during every call to paint(). First of all, currently it's leaking memory quite a bit because those labels allocated during every paint event are never deleted. Secondly, the geometry of a widget is calculated upon first time shown so you should call something like QWidget::adjustSize() or QWidget::ensurePolished() first. But anyway, what's the point of doing so expensive operations such as constructing a label with text and taking a screenshot of it when you could just paint the text with QPainter?
    J-P Nurmi

  15. #15
    Join Date
    Mar 2008
    Posts
    29
    Thanks
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Model View - Delegate - setIndexWidget

    ups, that's right, obviously it is much more performant to render the items manually, but I thought, it'll be easier for me to implement, because so I only need to create a simple widget and let this paint. I need to fill the table cells with some text and some icons, so I don't know how to get the icons on the right side of the cell, beside the text information.
    The item (cell) has to be like this "abstract graphic":

    Course 4711 From: 01.01.2008 To: 10.01.2008 ICON1 ICON2

    Sometimes there has to be one icon, sometimes two. So I think I have to calculate some space to render between the text and the icon. Do you have any idea how to solve this ?

    I think, it will go in this direction, or ?:
    /*
    QPoint iconStart = ... end of text
    QPoint iconEnd = ... end of cell ???
    QRect iconsRect = ...
    painter->drawPixmap(iconsRect, QPixmap("test.png"));
    */
    Last edited by starcontrol; 2nd April 2008 at 14:23.

  16. #16
    Join Date
    Mar 2008
    Posts
    29
    Thanks
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Model View - Delegate - setIndexWidget

    I think, i will have to devide the cell into two or more rectangles and paint into the devided new rectangles, perhaps like this:

    Qt Code:
    1. void SchulungsplanDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex &index) const
    2. {
    3. if (index.column() == 3 && index.row() == 2)
    4. {
    5. painter->save();
    6.  
    7. if (option.state & QStyle::State_Active)
    8. painter->fillRect(option.rect, QBrush(QColor(Qt::darkGreen), Qt::SolidPattern));
    9. if (option.state & QStyle::State_Selected)
    10. painter->fillRect(option.rect, QBrush(QColor(Qt::red), Qt::SolidPattern));
    11.  
    12. QRect rect1 = QRect(option.rect->topLeft(),
    13. QPoint(option.rect->center()->x(), option.rect->bottomLeft()->y()));
    14.  
    15. QRect rect2 = QRect(QPoint(option.rect->center()->x(), option.rect->topRight->y()),
    16. option.rect->bottomRight());
    17.  
    18. painter->setPen(QColor(Qt::white));
    19. painter->drawText(rect1, Qt::AlignCenter, " RECT1 ");
    20. painter->setPen(QColor(Qt::yellow));
    21. painter->drawText(rect2, Qt::AlignCenter, " RECT2 ");
    22.  
    23. /*
    24. QPoint iconStart = ... end of text
    25. QPoint iconEnd = ... end of cell ???
    26. QRect iconsRect = ...
    27. painter->drawPixmap(iconsRect, QPixmap("test.png"));
    28. */
    29.  
    30. painter->restore();
    31. }
    To copy to clipboard, switch view to plain text mode 

  17. #17
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Model View - Delegate - setIndexWidget

    Yes, that's basically how QItemDelegate does it too. It divides to whole area to sub-areas for possible icon, checkbox, text etc. QRect should have enough helpful methods for the calculation and QStyle::alignedRect() might also become handy especially if you have to take both layout directions into consideration.
    J-P Nurmi

Similar Threads

  1. hierarchical model in a flat view
    By gniking in forum Qt Programming
    Replies: 4
    Last Post: 10th November 2009, 21:17
  2. Help with Model View
    By weepdoo in forum Qt Programming
    Replies: 13
    Last Post: 12th October 2007, 11:32
  3. Model, View and Proxy
    By No-Nonsense in forum Qt Programming
    Replies: 2
    Last Post: 21st November 2006, 09:50
  4. Model - View Programming doubt.
    By munna in forum Qt Programming
    Replies: 4
    Last Post: 28th April 2006, 14:01
  5. Replies: 6
    Last Post: 20th April 2006, 11:23

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.