Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I asked this question on Reddit and was directed here. http://www.reddit.com/r/Ubuntu/comments/vhadl/quickly_dynamic_ui/

Unfortunately I am having the same issue and the problems seems that you can only use .add() on a widget once. So here is my code,

self.ui.labels = []
for titles in entries:
    label = Gtk.Label()
    self.ui.labels.append(label)         
    self.ui.viewport1.add(self.ui.labels[-1])
self.ui.paned1.show_all()

Now, for fun I decided "What would happen if I just manually did..."

self.ui.viewport1.add(Gtk.Label())
self.ui.viewport1.add(Gtk.Button())
self.ui.viewport1.add(Gtk.Entry())

For my first code snippet I get this error,

Gtk-CRITICAL **: gtk_viewport_add: assertion gtk_bin_get_child (bin) == NULL' failed

The error happens an unknown amount of times because the list entries can vary in length, but for my second code snippet it happens exactly twice. This means that when I viewport1.add() it works the first time, but all adds after that receive the error above.

So my question, is there a way in python to use .add() on the same widget more than once?

share|improve this question

1 Answer 1

up vote 1 down vote accepted

Gtk has different types of containers. Right now, you are working with a GtkBin container, which is a type of container that only supports a single child. You need a container that supports more than one child. To do that, just create a container of your choice and add it to the viewport (like an ordinary widget). There are a few choices here, and they are all listed in the Gtk documentation on containers.

One way to do this is with a GtkBox:

self.ui.labels = []
for titles in entries:
    label = Gtk.Label()
    self.ui.labels.append(label)         
    self.ui.viewport1.add(self.ui.labels[-1])
self.ui.paned1.show_all()

# First, we need to create a box to hold all our widgets
box = Gtk.Box()
box.set_orientation(Gtk.Orientation.VERTICAL)

# Now add our widgets to the box, one by one, from the bottom
box.add(Gtk.Label())
box.add(Gtk.Button())
box.add(Gtk.Entry())

# We need to add the box to the viewport
self.ui.viewport.add(box)

box.show_all()

Once you get the hang of it, you might want to play with some other functionality. Instead of blindly adding widgets to the box, the pack_start and pack_end functions for GtkBox give you control for each widget you add. You can set whether a child is given all the available space, and how much space to put around it. For some cases you might be interested in GtkGrid, which is a more powerful container that supports multiple rows and columns.

share|improve this answer
    
Thanks, I must of missed that information in the viewport documentation. I am quite new to GUI Programming and this was a good lesson learned. –  Dillon Gilmore Jun 23 '12 at 21:41
    
A good way about this is if you tinker with Glade. You'll get a good feel for what's possible, at least, and how things tend to look. Once you start working with containers that do layout, there are some little details to keep in mind like halign and valign (Gtk.Align.FILL makes a widget take up as much space as it has available, rather than just what it needs), hexpand and vexpand, widget padding and column / row spacing. The C documentation is really handy for all of this, too :) –  Dylan McCall Jun 23 '12 at 21:55

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.