PDA

View Full Version : Better understanding of the ModelView archtecture



scarleton
27th June 2010, 15:27
I have read through Qt’s documentation on ModelView a number of times now, but I cannot figure out how best to apply that to my problem. I am hoping someone here can help me out.

Conceptual database model:

Table: Customer
Fields: customer_id, name, etc

Table: Image
Fields: image_id, customer_id, image_src_path

A customer can have zero or more images. There can be hundreds of customers upwards of a thousand at times. Each customer might have as many as 50 images, but there is no limit on the actual count.

The system will copy all the images for a given customer from the image_src_path to a new location based on the Customer’s name. The view is ONLY showing customers, the number of images per customer, and the "copy state" (more on what I mean in a moment). Ignoring the copy state for a moment , the view is pretty simply, since the tables are a database, getting the image count is easy.

Q1: In the ModelView architecture, where would the command to copy the images exist? This must be looked at as a command because there are two general configurations of this command: One is where the files are local (db is SQLite) and the Qt is going to be doing the copy. The other is where the files are remote (db is Firebird) and Qt is simply calling a stored proc so the db server does the copy.

Copy State: The system has the concept of a copy state. Another module of the whole system allows customers to add and remove images. So let’s assume customer Bigboy initially added 4 images. Before the copy command takes place, the state would be "uncopied". Once the Qt program issues the command, the images as a whole, would be in a "copied" state. When Bigboy goes back to the other system and adds and/or removes an image, than the state of all the images in general is "modified".

There are two different approaches to determining the copy state. One is to get the image_src_path from the db and have the Qt Model do all the work. This works fine for the local mode, but not viable for the remove mode. The other approach is to write some extension methods in the DB to return the information about the files so the client and determine state. Either way, it is simply a matter of the Model calling a GetState(customer_id) command to get state.

Q2: Since the number of customers is relatively small, less than a thousand, it seems the easiest to allow the Qt model to load up the whole thing in memory. On the other hand, because the total number of images could be upwards of 50,000 x2 (src and dst), the Qt Model should not try to determine the Copy State for everything at one time, rather it should only issue the GetState(customer_id) for the customers that are actually being display. How do one do that with a Qt Model?

tbscope
27th June 2010, 17:25
Q1: In the ModelView architecture, where would the command to copy the images exist?
Copying is an action you do on or with the data. The model contains and handles the data, the view only takes care of displaying the data.
To keep with the model view design pattern, any data handling should be done or initiated by the model. In other words, the copying should be done by the model, or it should be initiated by the model and done in another class (a file manager for example).


Q2: Since the number of customers is relatively small, less than a thousand, it seems the easiest to allow the Qt model to load up the whole thing in memory. On the other hand, because the total number of images could be upwards of 50,000 x2 (src and dst), the Qt Model should not try to determine the Copy State for everything at one time, rather it should only issue the GetState(customer_id) for the customers that are actually being display. How do one do that with a Qt Model?
Why not store the state in the database itself? This way you don't have to create a more complex model, just use any of the QSql models. A function like GetState could do a query for customer_id. And if you do it in a transaction, you can do it for all your customers at once. Or you can reimplement fetch more so that when you scroll the view and there are some items on the screen that do not have the state filled in, you can get those at that moment via the GetState function. Or, you can run a fetch timer in the background do fill in the blanks in blocks of 100 customers (or more) (asynchronously)

scarleton
27th June 2010, 18:02
Copying is an action you do on or with the data. The model contains and handles the data, the view only takes care of displaying the data.
To keep with the model view design pattern, any data handling should be done or initiated by the model. In other words, the copying should be done by the model, or it should be initiated by the model and done in another class (a file manager for example).So if I understand you correctly, I should derive my own model and add a function on that which does or initiates the copy. Cool, thank you.
Why not store the state in the database itself? This way you don't have to create a more complex model, just use any of the QSql models. A function like GetState could do a query for customer_id. And if you do it in a transaction, you can do it for all your customers at once. Or you can reimplement fetch more so that when you scroll the view and there are some items on the screen that do not have the state filled in, you can get those at that moment via the GetState function. Or, you can run a fetch timer in the background do fill in the blanks in blocks of 100 customers (or more) (asynchronously)The issue is that outside forces can and do muck with the images, so any state put into the database can and will become stail.

tbscope
27th June 2010, 18:12
So if I understand you correctly, I should derive my own model and add a function on that which does or initiates the copy. Cool, thank you.
Yes. It shouldn't be difficult.

Edit: Or, and I don't like this idea myself, create a class that contains the model, and then write functions in this 'super class". Then you don't have to subclass a model.


The issue is that outside forces can and do muck with the images, so any state put into the database can and will become stail.
I did understand your wrong. In that case, I guess you can use a file system watcher (also in the model): http://doc.qt.nokia.com/4.6/qfilesystemwatcher.html

scarleton
27th June 2010, 18:59
I did understand your wrong. In that case, I guess you can use a file system watcher (also in the model): http://doc.qt.nokia.com/4.6/qfilesystemwatcher.htmlAgain, a file system watcher is not viable, because as I stated before: outside forces can and DO change the state. Using a file system watcher would mean a service running 24/7 and this is a bit over kill. The safest and cleaned way to accurately show the user the state is to check the state on demand. So, the question remains:

Q: In a Qt Model, how does one have one column that is dynamic upon display.

tbscope
28th June 2010, 05:44
Q: In a Qt Model, how does one have one column that is dynamic upon display.
A model is (or should be) dynamic by design. You don't need to do anything else but set the new data in the correct place.

boudie
28th June 2010, 07:07
Normally, you implement your own data() method that returns the value for a given ModelIndex. It could look something like this:




QVariant CalculatorTapeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) return QVariant();


if (role == Qt::TextAlignmentRole)
{
... alignment code ...
}


if (role == Qt::DisplayRole)
{
*** This is where you should check the state of your dynamic items ***
... return data for requested item ...
}
}