Results 1 to 4 of 4

Thread: Item Delegate Painting

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Item Delegate Painting

    I'm writing a delegate that I wish to use integrate with Drag and Drop on a QListView.
    The idea is that if people drag a file from the desktop into the application the filename will be copied to the clipboard, then as they drag the mouse over items, either in the list, if they are hovering directly over the item, then when they release they will be asked if they want to replace the existing item, or if it's within a range of pixels from the top or bottom of the item, then I want to draw a red line between the items, the "insert" the dragged filename to this location.

    As a start I've sub-classed QAbstractItemDelegate and implemented "paint" and "sizeHint".
    I thought to begin with I'd just draw a straight line through the text on the selected item, so I hardcoded some values in, basically drawLine(left, height of item / 2, right, height of item / 2). This works fine, regardless of the item I click on the entire list gets cleared and the red line gets drawn through the first item.

    Can anyone suggest what I need to add to the following code to draw through the item selected and retain the item data, I'm guessing I need to use the QModelIndex parameter.

    Qt Code:
    1. #ifndef DRAGDROPLISTITEMDELEGATE_H
    2. #define DRAGDROPLISTITEMDELEGATE_H
    3.  
    4. #include <QAbstractItemDelegate>
    5.  
    6.  
    7. class DragDropListItemDelegate : public QAbstractItemDelegate
    8. {
    9. Q_OBJECT
    10.  
    11. public:
    12. DragDropListItemDelegate(QObject* parent = 0);
    13.  
    14. QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex &index) const;
    15. void setEditorData(QWidget* editor, const QModelIndex& index) const;
    16. void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
    17. void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const;
    18. void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
    19. QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
    20.  
    21. };
    22.  
    23. #endif // DRAGDROPLISTITEMDELEGATE_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "DragDropListItemDelegate.h"
    2.  
    3. #include <QSpinBox>
    4. #include <QLineEdit>
    5. #include <QModelIndex>
    6. #include <QString>
    7. #include <QColor>
    8. #include <QPainter>
    9. #include <QSize>
    10.  
    11. DragDropListItemDelegate::DragDropListItemDelegate(QObject* parent)
    12. {
    13.  
    14. }
    15.  
    16. QWidget* DragDropListItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex &index) const
    17. {
    18. QLineEdit* editor = new QLineEdit(parent);
    19.  
    20. return editor;
    21. }
    22.  
    23. void DragDropListItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
    24. {
    25. QString value = index.model()->data(index, Qt::DisplayRole).toString();
    26. QLineEdit* lineEdit = static_cast<QLineEdit*>(editor);
    27. lineEdit->setText( value );
    28.  
    29. }
    30.  
    31. void DragDropListItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
    32. {
    33. QLineEdit* lineEdit = static_cast<QLineEdit*>(editor);
    34. QString value = lineEdit->text();
    35.  
    36. model->setData(index, value, Qt::EditRole);
    37. }
    38.  
    39. void DragDropListItemDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
    40. {
    41. editor->setGeometry(option.rect);
    42. }
    43.  
    44. void DragDropListItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
    45. {
    46. painter->drawLine( option.rect.left(), option.rect.height() / 2, option.rect.right(), option.rect.height() / 2 );
    47. painter->setPen( QColor(255, 0, 0) );
    48.  
    49. }
    50.  
    51. QSize DragDropListItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
    52. {
    53. return QSize(10, 10);
    54. }
    To copy to clipboard, switch view to plain text mode 

    Also, the paint event is called in this case when I click an item. Will it also fire when I'm dragging over an item?

  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: Item Delegate Painting

    Based on what I know the default behaviours of all the views is like you describe it, so there is no need for a custom delegate. Just enable drag & drop for your model and view and maybe reimplement dropEvent() to pop up the replacement dialog before calling the base class implementation.

  3. #3
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Item Delegate Painting

    From a test a did in the past I recall that there wasn't a "guide" (the red line) indicating where the item was going to be placed, so I figured I'd need a delegate to do that.

    I actually want it be be like in Excel when you move rows around. If you drag a row in between you get a really wide H shape on the division between the rows in a greyed out colour. I want that in say red, and possibly even slide what's below the insertion point down a row height as a really clear indication of where it's going, kind of like the way dock widgets slide apart to make a space.

    The software project I'm working on is (intended to be) a better version of a system I supported a few years ago. Whilst I'm working on the re-invention I want to make the user experience as easy and obvious as possible.

    I'll try getting the drag and drop done first and see how that behaves, then attempt to implement this delegate if it doesn't work.
    If I do need the delegate, how do I work around my original question? Do I need to loop through each QModelIndex, get the data() member then paint the text manually onto the QPainter context provided, essentially managing the entire rendering process?
    Maybe I just need to look at the QItemDelegate implementation.

  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: Item Delegate Painting

    Quote Originally Posted by stevey View Post
    From a test a did in the past I recall that there wasn't a "guide" (the red line) indicating where the item was going to be placed, so I figured I'd need a delegate to do that.
    There is, just set the showDropIndicator property to true.

    I actually want it be be like in Excel when you move rows around. If you drag a row in between you get a really wide H shape on the division between the rows in a greyed out colour. I want that in say red, and possibly even slide what's below the insertion point down a row height as a really clear indication of where it's going, kind of like the way dock widgets slide apart to make a space.
    In that case delegates won't help you. You have to implement it in the view. The delegate renders a single item, not "a row of items" or "something around items".

Similar Threads

  1. QMovie from inside a custom item delegate
    By Crazy_Hopper in forum Qt Programming
    Replies: 3
    Last Post: 7th May 2008, 16:18
  2. Replies: 1
    Last Post: 19th April 2007, 23:23
  3. Painting and collision detection
    By aamer4yu in forum Qt Programming
    Replies: 1
    Last Post: 18th October 2006, 09:57
  4. [Qt4] Noob and custom Item Delegate
    By naresh in forum Newbie
    Replies: 36
    Last Post: 19th March 2006, 16:46
  5. how change the QListBox item position by pixel
    By roy_skyx in forum Qt Programming
    Replies: 2
    Last Post: 20th January 2006, 02:34

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.