Results 1 to 2 of 2

Thread: Custom model with a QTreeView... I don't understand how to add drag&drop support

  1. #1
    Join Date
    Jul 2009
    Posts
    74
    Thanks
    2
    Thanked 6 Times in 6 Posts

    Question Custom model with a QTreeView... I don't understand how to add drag&drop support

    Hi !
    I have a treeview with a custom model (read only) working perfectly...
    but now I want to implement drag&drop support (but only inside the treeview! not to other widgets or from other widgets)

    I have read all the documentation and books... but I think that I don't understand it well.

    This is only a simplified example to expose my doubts and questions about that.

    Important Note: The treeview cannot be edited by user.
    (I can change de model programatically... but not directly in the view)

    These are my classes:

    Qt Code:
    1. class Teacher
    2. {
    3. ...
    4. ...
    5. private:
    6. QString m_name; // this will be a column in the treeview
    7. QString m_phone; // this will be a column in the treeview
    8. School * m_school // "parent" school of the teacher
    9. // much more complex data that is not going to be showed in the treeview
    10. QPicture m_photo;
    11. MyOtherDataTeacher m_otherData;
    12. etc
    13. ...
    14. ...
    15. }
    16.  
    17. class School
    18. {
    19. ...
    20. ...
    21. private:
    22. QString m_name; // this will be a column in the treeview
    23. QString m_address; // this will be a column in the treeview
    24. // much more complex data that is not going to be showed in the treeview
    25. QDate m_openingDate;
    26. MyOtherDataSchool m_otherData;
    27. etc
    28. ...
    29. ...
    30. }
    31.  
    32. class SchoolTeacherModel : public QAbstractItemModel
    33. {
    34. ...
    35. ...
    36. private:
    37. QList<School *> m_schools; // each school will be a "top level item" in the treeview
    38. QList<Teacher *> m_teachers; // each teacher will be a child of his school
    39. // the model contains other data not needed by the view
    40. QDate m_whateverdate;
    41. MyOtherData m_whatever;
    42. etc
    43. ...
    44. ...
    45. }
    To copy to clipboard, switch view to plain text mode 

    [First step]
    With that data model I want to create a read-only tree like this:

    + School1 street A, 3-3
    teacher1 555-644-247
    teacher2 555-641-577
    + School2 street B, 4-3
    teacher3 555-644-247
    teacher4 555-641-577
    + School3 street C, 2-6

    (under each school we can see their teachers)

    That's pretty easy...
    I only need to reimplement these methods in SchoolTeacherModel:
    Qt Code:
    1. QModelIndex index(int row, int column,
    2. const QModelIndex &parent = QModelIndex()) const;
    3. QModelIndex parent(const QModelIndex &index) const;
    4. int rowCount(const QModelIndex &parent = QModelIndex()) const;
    5. int columnCount(const QModelIndex &parent = QModelIndex()) const;
    6. QVariant data(const QModelIndex &index, int role) const;
    To copy to clipboard, switch view to plain text mode 
    Everything very easy...
    Note that my "columnCount(...)" method is implemented in this way:
    Qt Code:
    1. int SchoolTeacherModel::columnCount(const QModelIndex &parent) const
    2. {
    3. return 2; // because this is the max number of columns that is going to be showed
    4. }
    To copy to clipboard, switch view to plain text mode 
    And that "data(...)" is implemented in this way (a bit simplified for brevity):
    Qt Code:
    1. QVariant SchoolTeacherModel::data(const QModelIndex &index, int role) const
    2. {
    3. if (!index.isValid())
    4. {
    5. return QVariant();
    6. }
    7.  
    8. if (role != Qt::DisplayRole)
    9. {
    10. return QVariant();
    11. }
    12.  
    13. // Important Note: I only support here data that is to be shown... but remember that internally School and Teacher has much more data that the view doesnt need...
    14. if (index.isSchool()) // <- this is a simplification
    15. {
    16. School * school = static_cast<School*>(index.internalPointer());
    17. switch (index.column)
    18. {
    19. case 0:
    20. return school->m_name; break;
    21. case 1:
    22. return school->m_address; break;
    23. default:
    24. return QVariant();
    25. }
    26. }
    27. else if (index.isTeacher()) // <- this is a simplification
    28. {
    29. Teacher * teacher = static_cast<Teacher*>(index.internalPointer());
    30. switch (index.column)
    31. {
    32. case 0:
    33. return teacher->m_name; break;
    34. case 1:
    35. return teacher->m_phone; break;
    36. default:
    37. return QVariant();
    38. }
    39. }
    40. return QVariant();
    41. }
    To copy to clipboard, switch view to plain text mode 

    That is my read-only model...
    and it is working perfectly. And I think that is corretcly implemented. (do you agree? or do you think that my columnCount(...) and data(...) are not correct?)

    In my imaginary window I have a button... "Create school with teachers"... (Insert a new school in my model)
    So in my model added this imaginary method:

    Qt Code:
    1. void SchoolTeacherModel::insertSchool(School * school)
    2. {
    3. beginInsertRows(QModelIndex(),m_schools.count(),m_schools.count());
    4. m_schools.insertItem(m_schools.count(), school);
    5. endInsertRows();
    6. }
    To copy to clipboard, switch view to plain text mode 

    This is working perfectly too. Now I can add new schools programatically.
    Note: I have not reimplemented these methods ->
    Qt Code:
    1. bool QAbstractItemModel::insertRows ( int row, int count, const QModelIndex & parent = QModelIndex() );
    2. bool QAbstractItemModel::setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole )
    To copy to clipboard, switch view to plain text mode 
    For the moment I don't need them ! (correct?)

    [Second step]
    Now I want to add support for "drag and drop" rows of the treeview
    (only drag and drop INSIDE the treeview... I only want that the user can move -for example- Teacher1 from School1 to School2. I don't want support for drad&drop to/from other widgets)

    What methods should I reimplement?
    Qt Code:
    1. Qt::DropActions DragDropListModel::supportedDropActions() const -> YES (move action)
    2. Qt::ItemFlags DragDropListModel::flags(const QModelIndex &index) const -> YES
    3. QStringList DragDropListModel::mimeTypes() const -> Not sure !
    4. QMimeData *DragDropListModel::mimeData(const QModelIndexList &indexes) const -> Not sure !
    5. bool DragDropListModel::dropMimeData(const QMimeData *data,
    6. Qt::DropAction action, int row, int column, const QModelIndex &parent) -> Not sure !
    7. QAbstractItemModel::removeRows(...) -> Not sure !!
    8. bool QAbstractItemModel::insertRows(...) -> Not sure !!
    9. bool QAbstractItemModel::setData(...) -> Not sure !! and... how?? only columns that are going to be showed? or all the data??
    To copy to clipboard, switch view to plain text mode 
    ....
    I need to reimplement any other method???
    ....
    and...
    Do I need to change my columnCount(...) and data(...) methods???
    For the moment, remember, they only "see" data that is going to be showed (name and address in School, and name a phone in Teacher)... but they don't see all the rest of data that is inside school and teacher classes.

    Of course i added this:
    myTreeView->setDragEnabled(TRUE);
    myTreeView->setAcceptDrops(TRUE);
    myTreeView->setDropIndicatorShown(TRUE);
    myTreeView->setSelectionBehavior(QAbstractItemView::SelectRow s);

    another side question:
    I don't like how the drop indicator looks...is possible to alter it??

    Thank you very much.
    Last edited by javimoya; 7th January 2011 at 10:18.

  2. #2
    Join Date
    Jul 2009
    Posts
    74
    Thanks
    2
    Thanked 6 Times in 6 Posts

    Default Re: Custom model with a QTreeView... I don't understand how to add drag&drop support

    any help?
    I have seen this easy solution:
    http://www.qtcentre.org/threads/1045...5291#post55291
    but it doesn't work !
    in tha example if you drag the first column... it works perfectly...
    but if you drag the second column... it create 2 rows !!!!

Similar Threads

  1. Replies: 1
    Last Post: 2nd August 2010, 20:16
  2. QTreeView: Drag and Drop
    By laugusti in forum Newbie
    Replies: 7
    Last Post: 19th March 2010, 19:05
  3. Drag and drop in QTreeView
    By Valheru in forum Qt Programming
    Replies: 3
    Last Post: 27th July 2008, 09:36
  4. drag and drop from QTreeView
    By Untersander in forum Qt Programming
    Replies: 1
    Last Post: 10th April 2006, 09:00
  5. Drag & drop for QTreeView
    By yogeshm02 in forum Qt Programming
    Replies: 2
    Last Post: 30th January 2006, 14:32

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.