Reputation: 2383
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?
Upvotes: 4
Views: 7855
Reputation: 11
A GTK Window can only contain one child. If you want to add multiple widgets then you need a layout container such as a box or a grid to hold them. Boxes are fine in GTK2 but in GTK3 the developers advise switching to grids as boxes are now deprecated in GTK3.
Upvotes: 1
Reputation: 28848
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()
Upvotes: 3
Reputation: 11614
Take a look into widget packing. Essentially you use window.add to add a special packaging container, which in turn contains the main widgets and/or additional containers.
sketch:
hbox = HBox()
window.add(hbox)
hbox.pack_start(widget1)
hbox.pack_start(widget2)
window.show_all()
Upvotes: 4