PDA

View Full Version : model conception



xavier
8th May 2006, 18:12
Hi all,

I have a question regarding the general conception of a Qt program.

I have an application that uses several types of items, say cars, drivers, mechanics, etc... (which all have a few specific values: brand of a car, age of a driver, etc...). The application has a list of every of these items, and performs an optimisation based on the informations they contain.

The user interface I'm building uses the model / view framework (mainly QTableModel and QTableView), to allow the edition of items. I built a model for every type of item (specializations of QTableModel), so I have: CarModel, DriverModel, etc...
All these classes actually share a lot of code: addItem, removeItem,... All I could find is to copy/paste the code in the different classes.

Is there not something simpler to do? I was thinking of using templates, and doing something like:
template<class T> class MyModel (which would include a few pure virtual functions)
which I would then specialize for cars, drivers, mechanics,...
But I see in the documentation of moc that signals and slots aren't supported in template classes.

So how could I keep my code simple, and avoid having the same piece of code copied in several classes?

Thanks,

Xavier

wysota
8th May 2006, 18:16
Implement the common parts of all models in a direct subclass of the table model and then subclass it and implement the parts that differ in the subclass.

QAbstractTableModel <-- MyCommonModel <-- { CarModel, DriverModel, MechanicModel }

xavier
8th May 2006, 18:32
Thanks for that quick reply.

Actually, I have a problem of types within the code that should be shared.
For instance, I have, for each class, a vector of pointers to objects.
i.e vector<Car*> or vector<Driver*>

now I have functions like removeElement(int num), which says:
theVector->erase(...)
I would like such functions to "templatized". It is every time the same function, but applying to different data types, i.e. vector<Car*> or vector<Driver*>.
That's why I was thinking of templates.

jacek
8th May 2006, 19:05
You can could an abstract base class for those objects:

. +--- Car
|
Object <---+--- Driver
|
+--- Mechanicand then create a class that would operate on a list of Object* and its subclasses (specific to each of these objects).

xavier
9th May 2006, 16:40
Yes, I could do that but there is a problem of type casts.

Indeed, the compiler can easily cast say between Car and Object, but vector<Car*> and vector<Object*> won't work.

So my library returns a vector<Car*>&, and the GUI cannot simply treat it as a vector<Object*>&. Except if I provide an explicit cast function, but I don't know how to do that. (I can not simply cast every item in a new vector, since I need to operate on the vector itself).

Anyway, the Qt documentation is not very clear about templates. It only says:

moc does not handle all of C++. The main problem is that class templates cannot have signals or slots. Here is an example:

class SomeTemplate<int> : public QFrame
{
Q_OBJECT
...

signals:
void mySignal(int);
};

So the derived class can't have signals. How about the base class? Is this valid:


template<class T> class SomeTemplate : public QTableModel
{
Q_OBJECT
...

signals:
void mySignal(int);
};

??

wysota
9th May 2006, 16:52
If classes share a common functionality, they can operate on the common base class of objects. In places where classes need a specialised functionality (so you implement them in a subclass), they can cast the object to a specialised class.

You really don't need templates here... And if you really really really want to have them, make sure that the template class won't introduce signals or slots -- implement them in a superclass, so that you don't have to moc the subclass.

jacek
9th May 2006, 16:53
How about the base class?
Probably it will work, as long as you won't have to run moc on the template (that is: you can't use Q_OBJECT or add new signals or slots).


Is this valid: [...]?
No, it's not. It's exactly the same situation as the one from the docs --- a template class with a signal.

xavier
10th May 2006, 10:34
If classes share a common functionality, they can operate on the common base class of objects. In places where classes need a specialised functionality (so you implement them in a subclass), they can cast the object to a specialised class.

You really don't need templates here... And if you really really really want to have them, make sure that the template class won't introduce signals or slots -- implement them in a superclass, so that you don't have to moc the subclass.

Well, I don't really really want to use templates... But, as I said earlier, I have a library whith functions which return vector<Car*>, vector<Driver*>, etc...
The function "removeElement", has exactly the same code every time but it operates on different types (vector<Car*> and vector<Driver*>).
I could create a base class "object", as Jacek suggested earlier. But how can I cast from vector<Car*> and vector<Driver*> to vector<Object*>, considering that my function operates on the vector itself (erase elements), so I can't just copy and cast every single element in a new vector!
and I don't want to modify the base library so that it returns a vector<object*>.

See what I mean?
Now this is more a C++ problem than a Qt one, so I guess I should search elsewhere. Anyway, thanks for your help.

Xavier