Okay, will try this.
And is there a way to do a complete refresh? Because sometimes there isn't only a simple row insertion, but a complete update of the whole data.
Okay, will try this.
And is there a way to do a complete refresh? Because sometimes there isn't only a simple row insertion, but a complete update of the whole data.
If you see doc for beginInsertRows and endInstertRows as Wysota said, you will notice its ROWS, not ROW.
So you can specify the indexes accordingly.
Yes, there is. Look at the methods and signals available for QAbstractItemModel.
I did look at the methods and signals of QAbstractItemModel already, all I found was "dataChanged" and "layoutChanged".. but this didn't work (Or I used it wrong?).
About beginInsertRows/endInsertRows: When I am adding 20 rows where each row has 10 children.. how would I call beginInsertRows? What do I pass as parent? The rows I am adding in a batch have different parents. Or do I call this method only for the top-level hirarchy?
Then look again, I see 18 signals in the class.
If you do that in one go then you just call it for the parent rows. The view will notice the children by itself then.About beginInsertRows/endInsertRows: When I am adding 20 rows where each row has 10 children.. how would I call beginInsertRows?
You can call those functions more than once, you know.The rows I am adding in a batch have different parents. Or do I call this method only for the top-level hirarchy?
Wysota, why do you count the signals instead of simply telling me which one I need?!
I know there are 18 and as I said I already tried the two that make sense for me: dataChanged() and layoutChanged() (of course including layoutAboutToBeChanged() as it's written in the docs).. so am I missing something? If yes, would you please be so kind and tell me?
I already told you once and you were not able to extrapolate on the knowledge you were given. I will tell you now again and then you will come back in two hours asking what to do if you want to delete rows from the model. The docs are not that long, it's much quicker to read through the whole page instead of bouncing around forums and waiting for people to point you back to the docs. It's also much quicker to look at one of the numerous great examples available in the docs.
An obvious one to try would be modelReset(), wouldn't it? If you start there, you will certainly come up with a proper sequence of calls you need to make to reset a model, especially since you were already given information on how to add rows to the model.I know there are 18 and as I said I already tried the two that make sense for me: dataChanged() and layoutChanged() (of course including layoutAboutToBeChanged() as it's written in the docs).. so am I missing something? If yes, would you please be so kind and tell me?
Last edited by wysota; 30th March 2012 at 13:09.
ednakram (26th June 2017)
wysota's responses like this come up on google searches. They should all be deleted. Almost always useless in trying to find a quick answer to a well formulated question.
Wysota:
Join Date Jan 2006
Posts 31,660
This sort of speaks for itself. I think Wysota can be forgiven if he sometimes doesn't respond well to people who expect to be spoon-fed code in answer to their questions.
I know this question was originally asked something like 2.5 years ago, but I've recently been trying to teach myself Qt (PyQt, actually), and I had this same question, which is how I found this post. Anyway...
In my case, I periodically update an underlying data set with raw data. My QAbstractItemModel-derived data model gets its data from this underlying data set. So, I ran into this issue of trying to figure out how to get the view to update every time the underlying data was updated. After a couple days of researching this on the web and trying various things, I came up with the very simple approach of just adding a method, called emitDataChanged(), to my model subclass. Here's the Python code for this method:
def emitDataChanged(self):
self.dataChanged.emit(QModelIndex(), QModelIndex())
From what I understand, this signal tells the view that "all the data has changed", so the view repaints everything. In the code that updates the underlying data, once all the data has been updated, I just call this method on the model, and the view automagically updates.
The nice thing about this approach is that the current state of the view remains intact. The approaches I tried in the beginning involved the whole beginModelReset/endModelReset thing, and although that caused the view to update, it also caused any expanded nodes to be collapsed, such that only the top-level nodes were visible after the update. It also caused the currently selected item to be lost. Using the dataChanged.emit(...) approach caused the view to behave exactly as I wanted it to: just repaint the whole thing. No selection lost, no nodes collapsed.
So that's it. Just thought I'd share in the hopes that this might help someone else in the future. Good luck.
another 3.5 years later i'd like to thank you for sharing this find. i also had a case where some underlying data constantly changes, but even the structure of the tree stays static. now a single one-liner allows updating hundreds of rows (driven by slider inputs) without the need to recreate the whole thing...
Just remember this is ok-ish for some models (and their use) but not for others. It's not a magic wand you can use in any case. There is more to it than redrawing a view when a model is modified.
Another 3.5 years late also I'd like to thank you very much for sharing this. What a wonderful method!
You can also do model.reset() which forces all the views to update themselves, refetch all the visible data.
Emitting the dataChanged signal is better if you are just making minor changes.
This is from Summerfield's PyQt book:
Note: Use beginResetModel() and endResetModel() instead whenever possible. Use reset only if there is no way to call beginResetModel() before invalidating the model. Otherwise it could lead to unexpected behaviour, especially when used with proxy models.Sorting the data makes all model indexes invalid and means that the views are now showing the wrong data. The model must notify the views that they need to update themselves by retrieving fresh data. One way to do this is to emit a dataChanged() signal, but for big changes it is more efficient to call QAbstractTableModel.reset(); this tells all associated views that everything is out-of-date and forces them to update themselves.
Last edited by neuronet; 11th October 2015 at 03:09.
Bookmarks