On 8/15/07, Darren Hart <[EMAIL PROTECTED]> wrote:
>
> On 8/14/07, Darren Hart <[EMAIL PROTECTED]> wrote:
> >
> > I'm trying to create a widget that lists checkbuttons with labels in a
> > tabular format that will adjust it's layout as the window is resized.  I am
> > currently using a table widget and have a working resize() method.
> > Unfortunately, I haven't been able to capture any kind of a resize event
> > other than size_allocate() which unfortunately caused an endless loop since
> > my resize()ing the table caused another size_allocate() call, etc etc.
> >
> > Reading the docs suggest that what I want to use is a configure_event
> > handler and that table is one of those special widgets with no XWindow of
> > it's own, that therefor will not receive configure_events.  I added my table
> > to an eventbox as mentioned in one of the tutorials, but I am not receiving
> > any configure events there either.  I tried adding the button_press_event
> > for a sanity check, and it is working fine.  I expect that the configure
> > event should occur when I resize my main window and the table expands as
> > it's container does (the column spacing increases).
> >
> > I am using libglade to build the interface, and am experimenting with
> > aggregation (vs. inheritance) for my object model.  To connect the signals,
> > the WidgetWrapper base class calls: signal_autoconnect(self) on the newly
> > constructed aggregate widget (and this is working well for the other
> > widgets, as well as for the button_press_event handler in this widget).
> > I've removed some superfluous code from the following example for clarity
> > (and it certainly isn't usable without all the requisite other classes).  I
> > did confirm that "on_configure_event" is the name I gave the handler in
> > glade, and I even tried connecting it manually via widget.connect() with
> > the same results.
> >
> > Can someone offer some insight as to what I might be doing wrong?  Is my
> > entire approach just not appropriate for pygtk?
> >
> >
> Attached is a stripped down example (without libglade or my app logic) of
> a self resizing table widget that needs to know when
> it has been resized.  The code is commented to indicate the problem - It
> works when I bind the window configure_event tot he table update_size
> method, but not when I bind the eventbox configure_event.  Obviously the
> widget isn't usually placed in a top level window, so I need to know when
> just it's immediate parent container get's resized.
>
> Any feedback would be most appreciated.  Thanks.



Turns out that configure_events are only handled by gtk.Window and
gtk.DrawingArea.  I added a flag to a size_allocate() signal handler that
avoids the infinite recursion.  Example attached.  Thoughts and comments on
this approach are more than welcome.  Thanks for the tips.

-- 
Darren Hart
#!/usr/bin/env python

# example autotable.py (based partly on eventbox.py)

import pygtk
pygtk.require('2.0')
import gtk

class AutoTable(gtk.Table):
    def __init__(self, cells):
        gtk.Table.__init__(self)
        self.labels = []
        self.last_allocation = None
        self.max_width = 0
        # create the labels and check for max_width
        for c in cells:
            l = gtk.Label(c)
            self.labels.append(l)
            self.max_width = max(self.max_width, l.size_request()[0])
        self.connect("size_allocate", lambda w,a: self.on_size_allocate(a))

    def on_size_allocate(self, allocation):
        # avoid endless recursion if the the allocated size is the same
        if self.last_allocation and \
           allocation.width == self.last_allocation.width:
            return
        self.last_allocation = allocation

        # resize it (with forced col spacing of 5)
        cols = max(1, allocation.width / (self.max_width+5))
        rows = max(1, len(self.labels)/cols)
        if len(self.labels) % cols:
            rows = rows + 1

        if (self.get_property("n-rows") != rows or 
            self.get_property("n-columns") != cols):
            self.set_size_request(cols*self.max_width+5, -1)
            for l in self.labels:
                if l.parent:
                    self.remove(l)
            self.resize(rows, cols)
            i=0
            for l in self.labels:
                x = i % cols
                y = i / cols
                self.attach(l, x, x+1, y, y+1)
                l.show()
                i = i + 1


class AutoTableExample:
    def __init__(self):
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_title("AutoTable Example")
        window.connect("destroy", lambda w: gtk.main_quit())
        window.set_border_width(10)
        auto_table = AutoTable(["one", "two", "three", "four", "five", 
                                "six", "seven", "eight", "nine", "ten"])
        window.add(auto_table)
        auto_table.show()
        window.show()


def main():
    gtk.main()
    return 0

if __name__ == "__main__":
    AutoTableExample()
    main()
_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to