By the way Tkinter does not support super() seems to be an 'old style' class, this is perhaps the raison why MI does not work in this context:

*Python 2.7.1rc1 (r271rc1:86455, Nov 16 2010, 21:53:40)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import Tkinter.Frame
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named Frame
>>> from  Tkinter  import Frame
>>> class App(Frame):
...     def __init__(self):
...         super(App, self).__init__()
...
>>> a=App()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: must be type, not classobj
>>> *

Steven, I corrected my code (even if I have a double Inheritance which is ok in this context):

* class ListObservable(Listbox, Observable):
    def __init__(self):
        Observable.__init__(self)
        self.listeContenu = StringVar()
        self.listeContenu.set(' '.join(sorted(data_base.keys())))
Listbox.__init__(self, listvariable=self.listeContenu, selectmode='single')
        self.grid(row=0, column=1, sticky=N+S+W)
        self.bind('<<ListboxSelect>>', self.onSelect)
        self._value = None

    def onSelect(self, e):
        if not self.curselection():
            self.setValue(0)
        else:
            self.setValue(self.get(self.curselection()))
        self.notify()

    def setValue(self, select):
        self._value = select

    def getValue(self):
        return self._value


class Entry1Observer(Entry, AbstractObserver):
    def __init__(self, sujet=None):
        AbstractObserver.__init__(self, sujet)
        self.text  = StringVar()
        Entry.__init__(self, textvariable=self.text)
        self.grid(row=2, column=2)

    def update(self):
        a = self.sujet.getValue()
        self.text.set(data_base[a][0])*

I still need a advice about the possible improvement specially for Entry observer object.

Regards
Karim

On 01/18/2011 07:31 AM, Karim wrote:

Thanks Izz, Luke, Steven and Alan!
That's I figured out with MI and super.
Steven I understand the point to have Listbox contains a Listbox.
Before the code was in App class and I extracted it to do an outside class making the mistake.
But magic of Python it's working (but I know it's awful).
The code is working but I am not totally happy because of many EntryObserver almost identical objects (except from update and grid() options)
Is it possible to simplify this structure?

Regards
Karim

The rest of the code is below:

#!/usr/bin/env python2.7
"""Module ObserverGraphique.py

Une implementation du design pattern Observer.
"""


from Tkinter import *
from observable import Observable
from observer import AbstractObserver


data_base = {
            'Employe1': ['Joel',   'Durant',  '0623'],
            'Employe2': ['Marc',   'Donce',   '0624'],
            'Employe3': ['George', 'Roux',    '0625'],
            'Employe4': ['Alain',  'Richard', '0626']
            }


__all__ = ['App', 'ListObservable', 'Entry1Observer', 'Entry2Observer', 'Entry3Observer']


class App(Frame):
"""Application graphique avec Tkinter implementant un Observer Design Pattern."""
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.master.title("Exemple : Observer Design Pattern")
        self.grid()
        self.createLabels()
        self.createObservable()
        self.createObservers()
        self.registerObservers()

   def createLabels(self):
        """Creation de widgets Label"""
        self.label1 = Label(text="Nom :")
        self.label2 = Label(text="Prenom :")
        self.label3 = Label(text="Poste :")
        self.label1.grid(row=1, column=1, sticky=W)
        self.label2.grid(row=2, column=1, sticky=W)
        self.label3.grid(row=3, column=1, sticky=W)

    def createObservable(self):
        """Creation de la listBox observable."""
        self.sujet  = ListObservable()

    def createObservers(self):
        """Creation des champs d'entre texte observateurs de la liste."""
        self.nom    = Entry1Observer(self.sujet)
        self.prenom = Entry2Observer(self.sujet)
        self.poste  = Entry3Observer(self.sujet)

    def registerObservers(self):
        """Enregistrement des observateurs."""
        self.sujet.attach(self.nom)
        self.sujet.attach(self.prenom)
        self.sujet.attach(self.poste)

class ListObservable(Listbox, Observable):
    """Creation de widget Listbox"""
    def __init__(self):
        #super(ListObservable, self).__init__()
        Observable.__init__(self)
        self._value = None
        self.listeContenu = StringVar()
        self.listeContenu.set(' '.join(sorted(data_base.keys())))
self.liste = Listbox(listvariable=self.listeContenu, selectmode='single')
        self.liste.grid(row=0, column=1, sticky=N+S+W)
        self.liste.bind('<Double-1>', self.onSelect)
        self.liste.selection_set(0)

    def onSelect(self, e):
        if not self.liste.curselection():
            self.setValue(0)
        else:
            self.setValue(self.liste.get(self.liste.curselection()))
        self.notify()

    def setValue(self, select):
        self._value = select

    def getValue(self):
        return self._value

class Entry1Observer(Entry, AbstractObserver):
    """Creation de widget Entry 1"""
    def __init__(self, sujet=None):
        #super(Entry1Observer, self).__init__(sujet)
        AbstractObserver.__init__(self, sujet)
        self.text = StringVar()
        self.entry = Entry(textvariable=self.text)
        self.entry.grid(row=1, column=2)

    def update(self):
        a = self.sujet.getValue()
        self.text.set(data_base[a][1])
        print a

class Entry2Observer(Entry, AbstractObserver):
    """Creation de widget Entry 2"""
    def __init__(self, sujet=None):
        AbstractObserver.__init__(self, sujet)
        self.text  = StringVar()
        self.entry = Entry(textvariable=self.text)
        self.entry.grid(row=2, column=2)

    def update(self):
        a = self.sujet.getValue()
        self.text.set(data_base[a][0])

class Entry3Observer(Entry, AbstractObserver):
    """Creation de widget Entry"""
    def __init__(self, sujet=None):
        AbstractObserver.__init__(self, sujet)
        self.text  = StringVar()
        self.entry = Entry(textvariable=self.text)
        self.entry.grid(row=3, column=2)

    def update(self):
        a = self.sujet.getValue()
        self.text.set(data_base[a][2])


if __name__ == '__main__':
    app=App()
    app.mainloop()

# ----- end of file ----- #

class AbstractObserver(object):
    """Interface general des observateurs"""
    def __init__(self, sujet):
        """Constructeur"""
        self.sujet = sujet

    def update(self):
        """Methode a implementer par les observateurs"""
        pass


On 01/18/2011 02:32 AM, Alan G wrote:
Steven D'Aprano<steve<at>  pearwood.info>  writes:

fact that multiple inheritance itself is often the wrong thing to use,
and even when it is right, it is often tricky to get it right. To put it
another way: don't use multiple inheritance unless you have to, there
are better ways, such as by composition.
Or use a language where MI is the normal and idiomatic way
to do things because the language assumes it and so it just
works. There are very few such languages but Lisp is one :-)

Sadly Python isn't, and when using MI I always avoid super()
Which is a huge shame since MI is where super() should
be most useful... But in my experience MI in Python is
definitely a place where explicit is better than implicit.

Alan G.



_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to