On Fri, May 28, 2010 at 10:25:51AM +0200, Alessandro Dentella wrote: > Ciao a tutti, [...] > Quando la finestra risulta incancellabile tramite il bottone kill, anche la > cancellazione tramite window-manager fallisce (AttributeError: G objectc has > no attribute 'title'). È come se la istanza 'g' sia stata resa monca > nonostante > esista ancora una finestra con una callback attiva che referenzia (in senso > forte) l'istanza stessa ed il suo metodo 'delete_event_cb'. Chiamo 'monca' > questa istanza nel senso che: > > * la weakref non la vede più > * la callback capisce che è una istanza di 'G' ma non ne vede l'attributo > di istanza 'title':: > > Traceback (most recent call last): > File "testd2_win.py", line 39, in clicked_cb > if self.title: > AttributeError: 'G' object has no attribute 'title' > > Conto su un vostro input per non andare in corto...
Vediamo un po' tutti i possibili problemi che possono sorgere: 1. il metodo `delete_event_cb` elimina il riferimento alla finestra ma il metodo può essere ancora chiamato dal padre e non essendoci più riferimenti a `self.w`... 2. gli unici riferimenti che hai agli oggetti `G` sono dei riferimenti deboli. a questo punto credo che tu debba andare a vedere come i riferimenti deboli siano implementati in pygtk. non sono molto preparato qui ma sicuramente il problema è questo. Accanto a `self.windows` affianca un'altra lista: `self.objects` con riferimenti forti, vedrai che a questo punti non hai più di questi problemi. per quanto ne so' la gestione dei riferimenti in pygtk è pensata per, ad eccezione di casi particolari, potersene dimenticare. nel momento in cui non ci sono più riferimenti python ad un oggetto gobject, questo viene deallocato. ps. ti allego la versione modificata. pps. la gerarchia che crei è con soli due livelli, perché allora non usi due classi distinte? ti allego la versione modificata ciao m.
import sys import weakref import gtk class Father(object): def __init__(self): self.children = [] self.objects = [] self.w = gtk.Window() self.h = gtk.HBox() self.kill_button = gtk.Button("kill") self.crea_button = gtk.Button("crea %s finestre" % n) self.w.add(self.h) self.h.add(self.crea_button) self.h.add(self.kill_button) self.w.show_all() self.w.connect('destroy', gtk.main_quit) self.kill_button.connect('clicked', self.clicked_cb) self.crea_button.connect('clicked', self.crea_molte_finestre) def crea_molte_finestre(self, win, ev=None): for i in range(n): obj = Child(title=str(i)) r = weakref.ref(obj) self.children.append(r) self.objects.append(obj) def clicked_cb(self, win): for g in self.children: obj = g() print obj if obj is not None: obj.destroy() del self.children[:] del self.objects[:] class Child(object): def __init__(self, title): self.title = title self.w = gtk.Window() self.w.set_title(title) self.h = gtk.HBox() self.kill_button = gtk.Button("kill") self.crea_button = gtk.Button("Finestra %s" % title) self.w.add(self.h) self.h.add(self.crea_button) self.h.add(self.kill_button) self.w.show_all() self.kill_button.connect('clicked', self.destroy) def destroy(self, win=None): self.w.destroy() if __name__ == '__main__' : if len(sys.argv) == 2: n = int(sys.argv[1]) else: n = 10 obj = Father() obj.w.connect('destroy', gtk.main_quit) try: gtk.main() except KeyboardInterrupt: sys.exit()
import os import gc import sys import weakref import gtk class G(object): def __init__(self, title=''): self.windows = [] self.objects = [] self.title = title self.w = gtk.Window() self.w.set_title(title) self.h = gtk.HBox() self.kill_button = gtk.Button("kill") self.crea_button = gtk.Button(title and "Finestra %s" % title or "crea %s finestre" % n) self.w.add(self.h) self.h.add(self.crea_button) self.h.add(self.kill_button) self.w.show_all() self.w.connect('delete-event', self.delete_event_cb) self.kill_button.connect('clicked', self.clicked_cb) self.crea_button.connect('clicked', self.crea_molte_finestre) def delete_event_cb(self, win, ev=None): self.w.get_toplevel().destroy() del self.w def crea_molte_finestre(self, win, ev=None): if self.title: return for i in range(n): #r = G(title=str(i)) obj = G(title=str(i)) r = weakref.ref(obj) self.windows += [r] self.objects.append(obj) def clicked_cb(self, win): if self.title: self.delete_event_cb(win) else: for g in self.windows: if g(): g().delete_event_cb(None, None) #if g: # se non usi weakref # g.delete_event_cb(None, None) self.windows = [] del self.objects[:] if __name__ == '__main__' : if len(sys.argv) == 2: n = int(sys.argv[1]) else: n = 10 obj = G() obj.w.connect('destroy', gtk.main_quit) try: gtk.main() except KeyboardInterrupt: sys.exit()
_______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python