Reputation: 5809
This doesn't work well:
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)
The problem is, image_log is used twice and GTK doesn't like it. Is there some .copy() method? Or should I just use plain vanilla deepcopy?
EDIT: Looks like there is no default way to clone objects in GTK. Factory will do the trick in this case.
GTK warning:
app/gui.py:248: GtkWarning: gtk_box_pack: assertion `child->parent == NULL' failed
hbox_errlog.pack_start(image_log)
Upvotes: 2
Views: 3051
Reputation: 176
all if you want to use the collection of widgets arranged in some fashion, again and again, let's say a box with one entry box and a label(can be complex as hell if you want) and want to use it multiple time in your application like depending upon condition how many similar tabs are needed but obviously working with different data that use composites with glade. With pygi(gi_composites) python library you can make your own widgets and use them multiple times. [https://github.com/virtuald/pygi-composite-templates][1]
Upvotes: 0
Reputation: 21
Use
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 this try ... except blocks are there because not all properties could be copied by using set_prop(get_prop). I haven't tested this for all properties and widgets yet, but it worked well for gtkEntry. Maybe this is slow, but it's nice the use :)
Upvotes: 2
Reputation: 49803
You could use a factory function to reduce code duplication
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(..))
There is a much more natural way. You will like it. In PyGTK 2.12+:
gtk.image_new_from_file(filename)
I had something in the back of my mind telling me this, but I didn't look it up.
http://www.pygtk.org/docs/pygtk/class-gtkimage.html#function-gtk--image-new-from-file
Upvotes: 2
Reputation: 28386
Why not
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)
It is only an extra 2 lines of code, and maybe more efficient than cloning/copying the first image object.
That way you can treat out_button
and err_button
independently. But it should make sense to use the same gtk.Image()
object for both buttons ... it is just an image.
Edit To avoid duplication (seems like overkill though) you could write a factory for gtk.Image() objects from the same 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
Or something along those lines, you get the idea. But a factory seems like overkill unless you are producing loads of these things and need them independently parented in GTK. 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)
Maybe it is something to do with GTK resource management?
Upvotes: 1