2009-08-24 10 views
2

Cela ne fonctionne pas:Comment utiliser le même widget deux fois dans pygtk?

image_log = gtk.Image() 
    image_log.set_from_file("test.png") 

    self.out_button = gtk.Button() 
    self.out_button.add(image_log) 

    self.err_button = gtk.Button() 
    self.err_button.add(image_log) 

    another_box.pack_start(self.out_button, False) 
    another_box.pack_start(self.err_button, False) 

Le problème est, image_log est utilisé deux fois et GTK ne l'aime pas. Y a-t-il une méthode .copy()? Ou devrais-je simplement utiliser la copie en profondeur de vanille ordinaire?

EDIT: Il semble qu'il n'existe aucun moyen par défaut pour cloner des objets dans GTK. L'usine fera l'affaire dans ce cas.

avertissement GTK:

app/gui.py:248: GtkWarning: gtk_box_pack: assertion `child->parent == NULL' failed 
hbox_errlog.pack_start(image_log) 
+0

Quelle est votre sortie d'erreur GTK/PyGTK? –

Répondre

2

Vous pouvez utiliser une fonction d'usine pour réduire la duplication de code

def make_image_from_file(fname): 
    im = gtk.Image() 
    im.set_from_file(fname) 
    return im 

self.out_button.set_image(make_image_from_file(..)) 

Revisiter

Il y a une façon beaucoup plus naturelle. Vous l'aimerez. En PyGTK 2.12+:

gtk.image_new_from_file(filename) 

j'avais quelque chose dans le dos de mon esprit me disant cela, mais je ne l'ai pas chercher.

http://www.pygtk.org/docs/pygtk/class-gtkimage.html#function-gtk--image-new-from-file

+0

* shakes fist * :) ... Nice et concis. –

+0

Merci kaizer.se! Je savais qu'il devait y avoir une manière directe! – iElectric

1

Pourquoi ne pas

image_log = gtk.Image() 
image_log.set_from_file("test.png") 
image_logb = gtk.Image() 
image_logb.set_from_file("test.png") 

self.out_button = gtk.Button() 
self.out_button.add(image_log) 

self.err_button = gtk.Button() 
self.err_button.add(image_logb) 

another_box.pack_start(self.out_button, False) 
another_box.pack_start(self.err_button, False) 

Il est seulement un supplément de 2 lignes de code, et peut-être plus efficace que le clonage/copie le premier objet d'image.

De cette façon, vous pouvez traiter out_button et err_button indépendamment. Mais il devrait être logique d'utiliser le même objet gtk.Image() pour les deux boutons ... c'est juste une image.

Modifier Afin d'éviter les doubles emplois (semble comme surpuissant bien), vous pouvez écrire une usine pour gtk.Image() des objets de la même image.

def gtkimage_factory(num_objs, image_file): 
    i=0 
    imglist = [] 
    while i<num_objs: 
     img_ob = gtk.Image() 
     img_ob.set_from_file(image_file) 
     imglist.append(img_ob) 
     i+=1 
    return imglist 

Ou quelque chose dans ce sens, vous avez l'idée. Mais une usine semble être trop lourde à moins que vous ne produisiez charges de ces choses et ont besoin d'eux indépendamment dans GTK. Alors ...

image_list = gtkimg_factory(2, "test.png") 

self.out_button = gtk.Button() 
self.out_button.add(image_list[0]) 

self.err_button = gtk.Button() 
self.err_button.add(image_list[1]) 

another_box.pack_start(self.out_button, False) 
another_box.pack_start(self.err_button, False) 

Peut-être quelque chose à voir avec la gestion des ressources GTK?

+1

J'utilise cette approche atm, mais la duplication de code est ce que j'ai toujours évité. Le problème réside parce que GTK définit parent à chaque widget (qui ne peut être qu'un). – iElectric

+0

Ah je vois.Même si le code est en double, ils doivent être des instances séparées de gtk.Image() ... donc ce n'est pas vraiment une duplication. J'ai ajouté un edit. –

+0

gtk.Image n'est pas seulement une image. C'est un widget affichant une image. – u0b34a0f6ae

2

Utilisez

def clone_widget(widget): 
    widget2=widget.__class__() 
    for prop in dir(widget): 
     if prop.startswith("set_") and prop not in ["set_buffer"]: 
      prop_value=None 
       try: 
        prop_value=getattr(widget, prop.replace("set_","get_"))() 
       except: 
        try: 
         prop_value=getattr(widget, prop.replace("set_","")) 
        except: 
         continue 
       if prop_value == None: 
        continue 
       try: 
        getattr(widget2, prop)(prop_value) 
       except: 
        pass 
return widget2 

Tout cela try ... except blocs sont là parce que toutes les propriétés peuvent être copiées à l'aide set_prop (get_prop). Je n'ai pas encore testé cela pour toutes les propriétés et les widgets, mais cela a bien fonctionné pour gtkEntry. Peut-être que c'est lent, mais c'est agréable l'utilisation :)

+0

Un grand merci pour cette fonction - une version légèrement plus mise à jour peut être trouvée dans http://stackoverflow.com/questions/20460848/templating-overflowing-content-with-glade-and-pygtk/20463925#20463925 ... Cheers! – sdaau

Questions connexes