On Tue, Sep 16, 2008 at 1:26 PM, Georg Altmann <ge****@george-net.dewrote:It is not about QT, it is about MVC. In MVC, code which implement the modelMarco Bizzarri schrieb:On Mon, Sep 15, 2008 at 9:37 PM, Georg Altmann <ge****@george-net.de>Ok, consider this: say the model needs to compute some sort of value by
wrote:
Hello,
I need some advice on how to implement model-view-controller. I am
trying to
develop a GUI application with PyQt, yet the problem rather applies to
mvc
in general, not just GUI applications.
Let's say the data is a list of objects with a common base class. The
views
are either a graphical representation of the objects or some form of
textual
input. The views shall change the model by using command objects (for
undo,
e.g. QUndoCommand).
My current approach is to implement the model as a class with a
list-like interface, with methods insert(), remove(), __getitem__(),
__setitem__(),...
and a signal to notify the views. The objects in the list have methods
to change their state as well.
My problem is, how do the commands interact with the model?
Let's say I have a command that modifies an object o in the list.
1) If list[key_to_o] returns a reference to the object, the command can
modify the object by using this reference, i.e. list[key_to_o].setX().
So there is no way for the list to know when the object changed - how
can it emit a singal then?
2) If list[key_to_o] returns a deep copy of the object,
copy_of_o = list[key_to_o], the command mofifies the copy and the
updates the list: list[key_to_o] = copy_of_o. Now the list can emita
signal in __setitem__().
While this may work, it seems awkward to copy around objects just to
perform
a possibly simple operation on them. Additionally it might not be
feasible
once objects get complex.
3) The interface of the classes of the objects could be reflected in
the list class, i.e. list.set_x_on_obj(key_to_obj,x). This would
probably make
the list class interface very bloated.
Of course the problem is not really limited to Python, my apologies if
I'm
totally off-topic here.
Regards
Georg
Well, I think one of the assumptions of the MVC is that the view can
be notified about the changes in the model. According to your
interface, the View can just be notified on operations about the
*whole* model, like adding or removing elements from it.
But the elements of your list-like class should be a part of your
model, and therefore should be able to notify the Views by
themselfves.
iterating over all objects in the list (for example some sort of hash).
Some kind of view then displays this value.
I could implement this by connecting a signal in each object to a slot in
the list class which in turn emits a signal which is connected to the
view.
But this implies all the objects in the list have to be instances of
QObject. I wonder if this is isn't a weird design, because for example
all value type classes in Qt don't derive from QObject, e.g. QString. My
list objects are not that simple (in terms of the data structure). So is
it ok to make them QObjects?
Did you take a look at this?
http://www.potu.com/man/doc.trolltec...ogramming.html
It seems to imply that you should use QtAbstractItemModel as a base
class for all your models. But since I'm not an expert about Qt, I
cannot really say.
Regards
Marco
Regards
Georg
--
http://mail.python.org/mailman/listinfo/python-list
should be completely ignorant of the libraries used for gui, and the gui part
of the application shouldn't acces directly to your model logic. This why
there is a third layer which abstract the logic of your datas and provide
standard operation for the gui code. This third layer (Controllers), should
be as few as possible coupled to the specificities of the gui library (but
must be).
The quoted papers explain rather well how to do this with QT (apart they call
controllers "delegates").
For medium to big project, don't be afraid to divide your program in three
packages, one for the model, in which you must not have any reference to QT
API of some sort, one for the controllers, where you provide events and
methods to manipulate your model, one for gui, where you just build windows,
subscribe to controller's events and use their functions as callbacks for
your widgets.
--
_____________
Maric Michaud