I have a QTableView and a Table Model, how do I inform the view that some data changed? or do I have to inform the model instead?
Is there a method to call? or should it be handled with slots/signals?
I have a QTableView and a Table Model, how do I inform the view that some data changed? or do I have to inform the model instead?
Is there a method to call? or should it be handled with slots/signals?
Check the QAbstractItemModel docs.
#1 You can just emit layoutAboutToBeChanged() and layoutChanged().The view will then update itself thoroughly.
#2 If you are inserting/removing/moving items.Check the protected function.
example:
After calling this function,the view will also update itself.Qt Code:
void MyModel::removeOneRow(int index) { beginRemoveRows(xx); ...//Do the remove action here. endRemoveRows(xx); }To copy to clipboard, switch view to plain text mode
#3 If you want to update a range of item.Check the dataChanged(xxx) signal.
It's not the goodbye that hurts,but the flashback that follow.
jcyangzh (6th October 2012)
Depends on the model and view design.
For example, if you change data in a database directly, that the model depends on, then all you would have to do is model->select() to refresh it. The view will get a signal from the model and show the changes.
When a user edits data directly in the view, and hits enter, the model should be updated.
No, I'm not inserting or deleting rows or columns, just changing individual cell's values.
It's not a database model either.
It's a custom model subclassed from QAbstractTableModel, the underlying data structure is a simple char[] array, with its dimensions not changing, and the Table View just displays their contents.
So, should I fire signal dataChanged() from the model or from the view?
How will the view know what has changed? Only the class (model) that has the data will know that, so you fire it from there. The view will receive the signal and update accordingly.
I wasn't clear enough, what I meant is if I had to call the view's signal dataChanged() or the model's signal dataChanged()
Ok I'll try to explain better:
I have a char array that's the underlying data structure.
I've subclassed QAbstractTableModel to act as the model.
I've added a Table view like this:
I have a timer that increments the underlying data, in its [0,0] position.
Right now, when I select a cell, or interact in some way with the table, then the cell's value is updated, because the table view somehow calls the model's data() method.
What I want to achieve is on each timer event, twice per second, the view updates the cell's values on the screen.
So please tell me what object should be the sender, and what signal of it, and what object should be the receiver, and what slot of it.
Or if I can achieve this with just a method call, instead of signals.
Edit:
I tried emitting layoutChanged() from the model, which works ok.
But I'm setting a timer with 0 msec timout and all I get is the signal emitted no more than 30 times per second, I need something faster.
Can't I just inform the view to update exactly the cell I know has changed?
I tried with the signal QAbstractItemModel::dataChanged, but I can't emit it from a QAbstractTableModel subclass, although it should inherit QAbstractItemModel's members, so what, aren't signals inherited?
Last edited by Petruza; 20th June 2010 at 20:30.
What about this?
void QAbstractItemModel::dataChanged ( const QModelIndex & topLeft, const QModelIndex & bottomRight ) [signal]
This signal is emitted whenever the data in an existing item changes.
If the items are of the same parent, the affected ones are those between topLeft and bottomRight inclusive
Then connect the signal to a slot where you view->show to refresh it?
How are you setting the model to the data? Seems like all you should have to do is re-run that code on the timer and the model/view signal slot will do what you want without further code.
Last edited by waynew; 20th June 2010 at 20:39.
moviemax (24th June 2011)
Hey Mole - doesn't seem right to me that the model doesn't know about the view.
What about: view->setModel(model)
and from the M/V architecture doc: "Signals from the model inform the view about changes to the data held by the data source."
What did you mean? Maybe only the view now knows about the model, but then what about that line in the doc?
I think you might just be misinterpreting the documents. The way I see it (and the way MVC is supposed to work) is that models simply inform any listeners of changes. The way this is done in Qt is that models emit signals (like void rowsInserted( const QModelIndex & parent, int start, int end) or void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight) ) and views simply connect to those. At no point is the model aware that something is connected to it, nor does it need to know.
Models are supposed to be just that, models of some underlying data structure. The whole point of MVC is keeping the model, view and controller separate from each other.
Well, I tried something and it worked fine. Each time I update my database, I set my tableview one more time
Qt Code:
model->setTable("Contacts"); model->select(); ui->tableView->setModel(model);To copy to clipboard, switch view to plain text mode
You should emit QAbstractItemModel::dataChanged() signal inside QAbstractItemModel::setData() function.
So, how do you implement QAbstractItemModel::setData() function in your custom model?
For more informations about model subclassing, you can look at Model Subclassing Reference.
Last edited by saa7_go; 24th July 2010 at 08:12. Reason: updated contents
Bookmarks