Roster Item is the equivalent of TreeItem in the example, appendChild is already there I just added removeChild.
appendChild:
removeChild:
Qt Code:
m_children.removeAll(item);To copy to clipboard, switch view to plain text mode
Roster Item is the equivalent of TreeItem in the example, appendChild is already there I just added removeChild.
appendChild:
removeChild:
Qt Code:
m_children.removeAll(item);To copy to clipboard, switch view to plain text mode
That's wrong. The model from the example was never fit to be fed live. When you manipulate the underlying data structure, you always have to call begin{Insert,Remove,Move}Rows() and end{Insert,Remove,Move}Rows().
But should I do:
beginMoveRows
removeChild
appendChild
endMoveRows
or
beginRemoveRows
removeChild
endRemoveRows
beginInsertRows
appendChild
endRemoveRows
Cause I tried both and still the program is crashing. Maybe I should call those functions somewhere earlier in the code?
//edit:
Ok I think I got it, I didn't change the Item's parent, so it thought it had other parent then it really had.
One other thing, when I select multiple items in my tree view, not all of them are moved, usually one or two stay in the same group. What could be the reason for that?
Last edited by arturo182; 31st May 2011 at 08:29.
My guess is that relative row numbers change when you start removing items and you are not taking that into account in your foreach loop.
Nope, I was wrong, the problem still exists. I can only move each item once, when I try to move it the second time it gets cloned (one copy stays in old group, and second is created in new group) on third move it crashes.
I still can't find what I'm doing wrong, I'm removing the item from old group, append it to new group, change item's parent. What else do I have to do. Can some one provide me with an example please?
The only change I made is to appendChild function, it now looks like this:
Qt Code:
void RosterItem::appendChild(RosterItem *item) { item->m_parent = this; m_children.append(item); }To copy to clipboard, switch view to plain text mode
All the previous code is unchanged. I tried adding beginMoveRows but it caused a crash, I tried to use it like so:
Qt Code:
beginMoveRows(oldGroup->index(), item->row(), item->row(), newGroup->index(), newGroup->rowCount()); oldGroup->removeChild(item); newGroup->appendChild(item); endMoveRows();To copy to clipboard, switch view to plain text mode
Maybe I should inherit QStandardItem or it's used for something else?
I tried moving same item three times, the first time it returned true, the second time it returned true but a debug message was displayed stating "endMoveRows: Invalid index" and the third time it returned false and crashed.
I'm sure you're right, I'm not reindexing rows' numbers correctly but I don't know how to fix it.
I don't like the idea of diving beneath the proxy level and extracting the internal pointer outside the model. In my opinion you should ignore the fact that the underlying model deals with some groups and contacts and you should focus solely on the top level of your model stack. Otherwise you should somehow resort the index list you get so that you can then traverse the list in a proper order that won't break your indexes. Remember that each change in the model invalidates all model indexes. You should first map all the indexes to items and then when you have them all, start moving them. It'd be best if you embedded all the logic directly in the model.
arturo182 (31st May 2011)
I just tried this:
Qt Code:
QList<RosterContact*> contacts; if(index.isValid()) { if(index.data(RosterItem::TypeRole) == RosterItem::Contact) { RosterContact *cnt = static_cast<RosterContact*>(index.internalPointer()); if(cnt) { contacts.append(cnt); } } } } foreach(RosterContact *cnt, contacts) { itemModel->moveToGroup(cnt, group); }To copy to clipboard, switch view to plain text mode
And it works great, no crashes and all items are moved. I know looping through contacts twice is not very efficient but I guess I don't have much choice.
What do you think of this solution?
It's certainly better than getting crashes. But you should really change wrap it all into your model API as using internalPointer() outside the model is just looking for trouble.
Bookmarks