Search code examples
pythongtkpygtkgtkentry

GtkWindow can only contain one widget at a time


I am using this code to retrieve and display an image from the web:

class Display(object):

    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect('destroy', self.destroy)
        self.window.set_border_width(10)

        self.image = gtk.Image()
        response = urllib2.urlopen('http://image.url/image.jpg').read()

        pbuf = gtk.gdk.PixbufLoader()
        pbuf.write(response)
        pbuf.close()
        self.image.set_from_pixbuf(pbuf.get_pixbuf())

        self.window.add(self.image)
        self.image.show()
        self.window.show()

    def main(self):
        gtk.main()

    def destroy(self, widget, data=None):
        gtk.main_quit()

It works, however I now want to display a text/entry box underneath the image (to retrieve the text later on). I added the following under self.image.show():

self.entry = gtk.Entry()
self.window.add(self.entry)
self.entry.show()

However, it spits out this warning then I run it, and the entry box doesn't appear:

ee.py:31: GtkWarning: Attempting to add a widget with type GtkEntry to a GtkWindow, but as a GtkBin subclass a GtkWindow can only contain one widget at a time; it already contains a widget of type GtkImage self.window.add(self.entry)

Not sure why it won't let me place more than one widget, does anyone have a solution for this?


Solution

  • Indeed packing is the answer.

    import gtk
    import urllib2
    class Display(object):
    
        def __init__(self):
            self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
            self.window.connect('destroy', self.destroy)
            self.window.set_border_width(10)
    
            # a box underneath would be added every time you do 
            # vbox.pack_start(new_widget)
    
            vbox = gtk.VBox()
            self.image = gtk.Image()
            response = urllib2.urlopen('http://1.bp.blogspot.com/-e-rzcjuCpk8/T3H-mSry7PI/AAAAAAAAOrc/Z3XrqSQNrSA/s1600/rubberDuck.jpg').read()
    
            pbuf = gtk.gdk.PixbufLoader()
            pbuf.write(response)
            pbuf.close()
            self.image.set_from_pixbuf(pbuf.get_pixbuf())
    
            self.window.add(vbox)
            vbox.pack_start(self.image, False)
            self.entry = gtk.Entry()
            vbox.pack_start(self.entry, False)
    
            self.image.show()
            self.window.show_all()
    
        def main(self):
            gtk.main()
    
        def destroy(self, widget, data=None):
            gtk.main_quit()
    
    a=Display()
    a.main()