2009-08-24 6 views
2

Dies funktioniert nicht gut:Wie benutze ich das gleiche Widget zweimal in 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) 

Das Problem ist, image_log verwendet wird zweimal und GTK es nicht mag. Gibt es eine .copy() -Methode? Oder sollte ich einfach Plain Vanilla Deepcopy verwenden?

EDIT: Sieht so aus, als ob es keine Standardmethode zum Klonen von Objekten in GTK gibt. Factory wird in diesem Fall den Trick machen.

GTK Warnung:

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

Was ist Ihre GTK/PyGTK Fehlerausgabe? –

Antwort

2

Sie könnten eine Fabrik-Funktion verwenden Code-Duplizierung

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(..)) 

Neubetrachtung

Es gibt eine viel natürlichere Art und Weise zu reduzieren. Du wirst es mögen. In PyGTK 2.12+:

gtk.image_new_from_file(filename) 

hatte ich etwas in der Rückseite meines Geistes mir dies zu sagen, aber ich sah es nicht auf.

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

+0

* schüttelt die Faust * :) ... Schön und prägnant. –

+0

Danke kaizer.se! Ich wusste, dass es einen direkten Weg geben muss! – iElectric

1

Warum nicht

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) 

Es ist nur eine zusätzliche 2 Zeilen Code ist, und vielleicht effizienter als das Klonen/Kopieren des ersten Bildobjekts.

Auf diese Weise können Sie out_button und err_button unabhängig behandeln. Aber es sollte Sinn machen, das gleiche gtk.Image() Objekt für beide Tasten zu verwenden ... es ist nur ein Bild.

bearbeiten Um Doppel (scheint wie Overkill obwohl) zu vermeiden Sie eine Fabrik für gtk.Image schreiben konnte() Objekte aus dem gleichen Bild.

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 

Oder etwas in diese Richtung, Sie bekommen die Idee. Aber eine Fabrik scheint wie Overkill, es sei denn, Sie produzieren Lasten dieser Dinge und brauchen sie unabhängig in GTK parented. Then ...

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) 

Vielleicht ist es etwas mit GTK Ressourcen-Management zu tun?

+1

Ich verwende diesen Ansatz atm, aber Duplizierungscode ist, was ich immer vermieden habe. Das Problem liegt darin, dass GTK Eltern zu jedem Widget (das nur eins sein kann) setzt. – iElectric

+0

Ah ich verstehe.Obwohl der Code dupliziert wird, müssen sie separate Instanzen von gtk.Image() sein ... also handelt es sich nicht wirklich um Duplikate. Ich habe eine Bearbeitung hinzugefügt. –

+0

gtk.Image ist nicht nur ein Bild. Es ist ein Widget, das ein Bild anzeigt. – u0b34a0f6ae

2

Verwenden

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 

All dies try ... except Blöcke geben es da nicht alle Eigenschaften unter Verwendung set_prop (get_prop) kopiert werden können. Ich habe dies noch nicht für alle Eigenschaften und Widgets getestet, aber es funktionierte gut für gtkEntry. Vielleicht ist das langsam, aber es ist schön die Verwendung :)

+0

Vielen Dank für diese Funktion - eine etwas aktualisierte Version kann in http://stackoverflow.com/questions/20460848/templating-overflowing-content-with-glade-and-pygtk/20463925#20463925 gefunden werden ... Prost! – sdaau

Verwandte Themen