Clearing/resetting a model in qt (removing all rows) - c++

I'm confused about the correct way to reset or clear the data associated with a QAbstractItemModel.
I'm writing an application in which the user can "start over" with a new set of data (empty, or small).
Should I be deleting the old model when the user makes this request? Or should I leave the model alone and just remove all of the rows?
Regards,
Dan O

Generally I would prefer to have the model react to changes and take the necessary actions to update it's view (indirectly ofcourse). However, programming models can be (=is) a PITA, so I would probably look through the fingers if I was reviewing code that created a new model and deleted the old one. Only do this if you are sure the user only will delete all rows. If the user may delete items from the model incrementally you're probably best off implementing removal properly in the first place...
Also, ModelTest might help you discover problems with your Qt models.

If the user is truly starting over with a new set of data, then it makes sense to me to simply delete the old model and create a new one. Simple, effective, and it matches up to what the user is doing.

I don't know which way it truly "better" but removing all the rows can be a rather simple function something like:
void MyModel::Clear(void)
{
// remove all data from internal data structures
...
// Call QAbstractItemModel::reset to ensure any views know that everything has changed.
reset();
}

Related

django-simple-history is storing changes twice

I tried django-simple-history and I discovered that every create or update is stored twice in the history model. I don't know which information is now useful for you to help me, but I use CBV's and model forms. I followed the instructions on how to install and setup and everything works fine. What I'm wondering is why there is a command line called clean_duplicate_history, which indeed removes all duplicates records. Thank you in advance for any help.
django-simple-history is naive. It works by creating a new simple history record on a post_save signal. Thus, it creates a new record every time you .save regardless of whether anything has changed. Because of that, duplicate records may increase significantly, which is why there is a clean_duplicate_history utility method. If the same record is being store twice and you're unsure why, it's likely that you're making multiple saves.

How to save relations of same class?

I had problem with saving relation to object with same class as parent.
You can check this problem here.
When I read that I can easily set the relationship after the promise has fulfilled here I created another example with that info in mind. But it doesn't work as I expect.
What I expect
Create array of Box instances with relation to previous Box instance in each.
And the question is if I'm doing something wrong or it's a bug. Let me know if you need any informations.
Your example isn't clear and simple enough. It needs to be isolated to EXACTLY what you're having an issue about and nothing else.
Having said that, I have had quite a bit of success saving relations to objects with the same class as parent, and so I don't think this is a problem with Ember Data or Ember.
Your code is quite convoluted and uses the sync library, which I'm not faimilar with.
It's a good idea to things as simply as possible at first, so try creating a jsbin with just the isolated functionality relating to saving relations that you're attempting, and then adding additional layers of functionality and testing after each add.

Qt 5.2 Model-View-Pattern: How to inform model object about changes in underlying data structure

I have a class used for permanent storage of some item that are organized in a table-like manner. This class is totally unrelated to Qt and comes from a different library. Lets call this class DataContainer for the rest of this question. It provides std-c++ compatible iterators to access and manipulate the content.
I need to display and modify that data through a Qt GUI. My idea was to create a class DataContainerQtAdaptor that inherits from QAbstractTableModel and stores a pointer to the DataContainer object. The DataContainerQtAdaptor serves as an adaptor to the DataContainer object and all manipulation from inside of my Qt app is done through this adaptor. Then I use a QTableView widget to display the information.
Unfortunately the DataContainer might be changed by threads/processes. (For example think of DataContainer as some C++ class that encapsulates a database connection and that database might be changed by someone else.)
Questions:
1) Assume I have a function that is called everytime the internal structur of the DataContainer object has been changed. What is the correct function of the QAbstractTableModel that must be called to inform the model of the underlying change? I need something like "Dear Model, your persistent storage backend changed. Please, update yourself and emit a signal to every attached view in order to reflect this change".
2) Lets say 1) is solved. What is the best way to avoid a "double" GUI update in case the change was triggered through the GUI? E.g: User clicks on a cell in the table widget -> table widget calls setData of the model -> model pushes change to backend -> backend triggers its own "onUpdate" function -> model re-reads complete backend (although it already knows the change) -> GUI is updated a second time
3) The user should be able to insert new rows/columns through the GUI and put data into it. But the position is detemined by this data, because the backend keeps the data sorted. Hence, I have the following problem: The user decides to create a new row at the end and the new data is pushed to the backend. When the backend/model is re-read this data is normally not at the last position, but has been inserted somewhere in the middle and all other data has been moved forward. Ho do I keep all the properties of the the table view widget like "selection of a cell" in sync?
I believe, there must be some simple standard solution to all these question, because it is the same way as QFileSystemModel works. The user selects a file and some other process creates a new file. The new file is displayed in the view and all subsequent rows move forward. The selection moves forward, too.
Matthias
Model Semantics
First of all, you must ensure that the QAbstractItemModel cannot be in an inconsistent state. This means that there are some signals that must be fired on the model before certain changes to the underlying data are done.
There is a fundamental difference between changes to structure and changes to data. Structure changes are the rows/columns of the model being added or removed. Data changes affect the value of existing data items only.
Structural changes require calling beginXxx and endXxx around the modification. You cannot modify any structure before calling beginXxx. When you're done changing the structure, call endXxx. Xxx is one of: InsertColumns, MoveColumns, RemoveColumns, InsertRows, MoveRows, RemoveRows, ResetModel.
If the changes affect many discontiguous rows/columns, it's cheaper to indicate a model reset - but be wary that selections on the views might not survive it.
Data changes that keep the structure intact merely require that dataChanged is sent after the underlying data was modified. This means that there is a window of time when a call to data might return a new value before dataChanged is received by the object that queries the model.
This also implies that non-constant models are almost useless from non-QObject classes, unless of course you implement bridge functionality using observer or similar patterns.
Breaking Update Loops
The Qt-idiomatic way of dealing with update loops on the model is by leveraging the item roles. It's entirely up to you how your model interprets the roles. A simple and useful behavior implemented by QStringListModel is simply to forward the role from the setData call to dataChanged, otherwise ignoring the role.
The stock view widgets react only to dataChanged with the DisplayRole. Yet, when they edit the data, they call setData with the EditRole. This breaks the loop. The approach is applicable both to view widgets and to Qt Quick view items.
Insertion of Data into Sorted Models
As long as the model properly emits the change signals when the sorting is done, you'll be fine.
The sequence of operations is:
The view adds a row and calls model's insertRow method. The model can either add this empty row to the underlying container or not. The key is that the empty row index must be kept for now.
The editing starts on an item in the row. The view state changes to Editing.
Editing is done on the item. The view exits the editing state, and sets the data on the model.
The model determines the final position of the item, based on its contents.
The model invokes beginMoveRows.
The model changes the container by inserting the item at the correct location.
The model invokes endMoveRows.
At this point, everything is as you expect it to be. The views can automatically follow the moved item if it was focused prior to being moved. The edited items are focused by default, so that works fine.
Required Container Functionality
Your DataContainer doesn't have enough functionality to make it work unless all access to it were to be done through the model. If you want to access the container directly, either make the container explicitly inherit QAbstractXxxxModel, or you'll have to add a notification system to the container. The former is an easier option.
Your core question reduces to: can I have model functionality without implementing some variant of the model notification API. The obvious answer is: no, sorry, you can't - by definition. Either the functionality is there, or it isn't. You can implement the notification API using an observer pattern if you don't want the container to be a QObject - then you'll need your model shim class. There's really no way around it.
The QFileSystemModel gets notified by the filesystem about individual directory entries that have changed. Your container has to do the same - and this amounts to providing a dataChanged signal, in some shape or form. If the model has items that get moved around or added/removed - its structure changes - it has to emit the xxxAboutToBeYyy and xxxYyy signals, by calling the relevant beginZzz and endZzz methods.
Indices
The most important underdocumented aspect of QModelIndex is: its instances are only valid for as long as the model's structure hasn't changed. If your model is passed an index that was generated prior to a structure change, you're free to behave in an undefined way (crash, launch a nuclear strike, whatever).
The whole reason for the existence of QModelIndex::internalPointer() is your use case of having an underlying, complex-indexed data container. Your implementation of the model's createIndex method must generate index instances that store references to the DataContainer's indices in some form. If those indices fit in a pointer, you don't need to allocate the data on the heap. If you need to allocate the container index storage on the heap, you must retain a pointer to this data and delete it any time the container's structure changes. You're free to do it, since nobody is supposed to use the index instance after a structure change.
From the documentation of method bool QAbstractItemModel::insertRows(int row, int count, const QModelIndex & parent = QModelIndex()):
If you implement your own model, you can reimplement this function if
you want to support insertions. Alternatively, you can provide your
own API for altering the data. In either case, you will need to call
beginInsertRows() and endInsertRows() to notify other components that
the model has changed.
The same goes for removeRows() and moveRows() (they have their own begin*() and end*() methods). For modifying data of existing item there's a dataChanged() signal.
Here's how it goes (answer for question 1):
Implement your own methods for inserting/deleting/modifying data, where each of those methods must look like this:
beginInsertRows(parentIndex, beginRow, endRow);
// code that modifies underlying data
endInsertRows();
beginRow and endRow must be provided to inform which where the rows will be inserted and how many of them (endRow-beginRow).
For beginDeleteRows() and beginMoveRows() it's the same.
When you have a method which simply modified data in existing item, then this method must emit signal at the end: dataChanged().
If you do a lot of changes in the data, it sometimes is simpler to just call beginResetModel() and endResetModel() in the method performing this huge modification. It will cause all views to refresh all data in it.
Answer for question 2:
This is up to the View class implementation if it will "double-update". When you enter data in the View, data is sent to the model through one of the edition methods in model (insertRows(), setData(), etc). Default implementation of those methods always use begin*() and end*() methods and so the proper notification signals are emitted by the model. All Views listen to those signals, including the one you used for entering the data, therefore the "double-update" will be performed.
The only way to define this behaviour is to inherit the View and reimplement its protected slots (like dataChanged() and similar) to avoid updating if the value was detected to be provided by this view.
I'm not sure if Qt views do that already or not. Answer to this requires someone more educated in Qt internals, or looking into Qt source code (which I don't have at the moment). If somebody knows this, please comment and I will update the answer.
I think it's not that bad to reload the data from model - it guarantees that what you see is indeed the value from the model. You avoid possible problems with the Editor and the View bugs.
Answer for question 3:
When you reload whole model, then there is no simple way to keep track of selection. In that case you need to ask view->selectionModel() about current selection and try to restore it after reload.
However if you do partial refreshing (using methods I described in answer 1), then the View will track the selection for you. Nothing to worry about.
Final comments:
If you want to edit data from outside of model class, you can do it. Just expose begin*() and end*() methods as public API, so other code that edits data can notify model and views about changes.
While it can be done, it's not a good practice. It may lead to bugs, because it's easy to forget about calling notification everywhere you modify the data. If you have to call model API to notify about changes, why not already move all editing code insise the model and expose editing API?

Django: How to implement system flags

I am developing an application in Django and I am curious on how I can go about adding a model such that only 1 row is only ever present (i.e. Singleton).
As an example, I'd like to maintain a set of boolean flags of the application i'm running as to whether: it's on or off (so I can manually turn it on or off, perhaps even per module).
I can't see any part of the docs explaining a good way to go about setting this up.
Any suggestions?
Not sure from you explanation in what context you require this but I have a model which holds a number of key/value pairs used in validator checks and other things. The keys are all needed by each implementation of the project but the values will differ between projects. The values should be maintainable by an admin user. The values usually do not need to change very much once set. Given that, I decided to put them in a model. It is a bit weird but simple enough.
You should be able to limit write access to the model to the one row for either your app or your users through your code.
only ever reference the first row in the QuerySet
row = MyVariables.objects.all()[0]
Test if there are rows first. if you think there might accidentally be more than one record then make sure it is ordered (but that should never happen if you did (1) correctly.
There are a couple of apps already dealing with this, check out http://djangopackages.com/grids/g/live-setting/
I'm also a bit confused on your goal, but I'd recommend looking at the Model Instance section of the docs. You should probably look at customizing the validation or cleaning of the model.
If your goal is to only have 1 row flagged in the table for your model: during the validation you can run a query to see if any other row is flagged, and update them to be not flagged. (or delete them).
This question Unique BooleanField value in Django may be helpful.

Undo functionality in an MVC design

I have a C++ application designed according to a classic Model-View-Controller pattern. The model is modified through a controller interface by an external source by means of a Command pattern. The commands are represented by an Action object (and its derivatives).
Now I want to be able to undo the modifications, but my problem is that I have no getters in my controller, only setters. This seems quite logical, since there's no reason someone should be able to get info about the model through the controller. Thus, I can't have my Action objects store the state of the Model, since they have no access to it.
How would one solve this? I'd like to keep my application as extendable as possible and I'm not quite sure which option is the best for that. The methods I though up so far are:
Putting getter methods in the controller. This seems to go against the MVC pattern.
Giving the Action a pointer to a View. The Action could then either:
Use individual getters to get the state of specific elements of the model to be modified.
Use a Memento method implemented by the Viewer.
Maybe there's an even better way to do this? Right now, to be the best option seems to be 2, suboption 1 (with suboption 2, I'd quite possible store a lot more state than necessary to undo one action).
Note: I know there's other questions on how to implement an undo action. However, the only answers I found gave suggestions to use a Command or Memento pattern. I know this is most probably the way to go. What I'm asking for is how to integrate this as cleanly & extendable as possible in an MVC design.
[Edit] What I don't like about the Memento pattern is that it forces me to store a complete state. Let's say my model is a 1000x1000 matrix and my Command is ChangeOneValueAtLocation. To be able to undo its changes, the ChangeOneValueAtLocation object only needs to store the previous value of the location it's changing, but that doesn't seem possible with Memento. The larger my model, the biggest this problem becomes.
[Edit 2] Another problem I have with Memento in the specific case of this application: for every method a Command object can execute on the Model, there's a method that does exact opposite (or can easily be coaxed to do so). This is why I would find it a waste to have to store the whole state, there should be no need to, reverting a single Command is very straightforward, the only problem is getting the data to be able to do it.
Also, I don't need to be able to undo a specific Command, only the topmost one on my history stack.
I also support the model layer containing undo support. There are quite a few ways to handle this in the model side. The first and most obvious is the models themselves remembering the history of the changes with "labels", but this is probably going to be difficult to synchronize for all your model classes.
One other option is to create a history manager that has a concept of a "transaction", which causes it to generate an undo point, and take a snapshot of your models, or start recording changes (for reduced memory usage), or record commands that cause model changes, etc.The models notify the manager on change, and finally you complete the transaction (or not, because the next start of transaction can be the end of the previous one). Once you add in the ability to rollback to a certain point, the work will be done. By making things slightly more complicated in this manager class, you can create an undo tree (like the one in emacs), so it is also quite a flexible way to approach it.
The above solution is not quite in the model layer, though. It is a support class that is driven by both the model and the controller. If you remove the transaction concept, then it is completely model-driven, but implementing the concept of an undo operation might be somewhat tricky. If you change it to act as a command proxy, it is the only entity used by your controllers, and is clearly a model. It is too rough a design at this point to choose one approach over another, but I am leaning towards the "transaction" model. It feels easy enough to implement.
I'd really recommend building the undo tree into your Controller
Building it into the model could run you into trouble:
the 'model' is usually fragmented per view (each view has it's own partial model)
this will lead to non-atomic undo (undoing part of an operation due to the view not knowing what other things (models) would have to be undone etc)
The controller is the 'action dispatcher', so it'd have to say
clone state (all models) snapshot
add action to history with reference to snapshot
run action
then undo would be
pop action off history stack (optionally push to 'future' stack)
restore snapshot
display view
Also, make undo work with highlevel actions (see Composite Pattern or Command Pattern)
Build the undo functionality in your model itself. Let you model keep a list of commands. Run the commands in the reverse order when your view passes an undo signal to the model.