iElectric
iElectric

Reputation: 5809

How to use the same widget twice in pygtk?

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

Answers (4)

camel.neeraj
camel.neeraj

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

Anonymous
Anonymous

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

u0b34a0f6ae
u0b34a0f6ae

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

Revisiting

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

Aiden Bell
Aiden Bell

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

Related Questions