PyGTK: dynamic label wrapping

Posted by detly on Stack Overflow See other posts from Stack Overflow or by detly
Published on 2009-12-12T15:24:04Z Indexed on 2010/03/25 19:13 UTC
Read the original article Hit count: 445

Filed under:

It's a known bug/issue that a label in GTK will not dynamically resize when the parent changes. It's one of those really annoying small details, and I want to hack around it if possible.

I followed the approach at 16 software, but as per the disclaimer you cannot then resize it smaller. So I attempted a trick mentioned in one of the comments (the set_size_request call in the signal callback), but this results in some sort of infinite loop (try it and see).

Does anyone have any other ideas?

(You can't block the signal just for the duration of the call, since as the print statements seem to indicate, the problem starts after the function is left.)

The code is below. You can see what I mean if you run it and try to resize the window larger and then smaller. (If you want to see the original problem, comment out the line after "Connect to the size-allocate signal", run it, and resize the window bigger.)

The Glade file ("example.glade"):

<?xml version="1.0"?>
<glade-interface>
  <!-- interface-requires gtk+ 2.16 -->
  <!-- interface-naming-policy project-wide -->
  <widget class="GtkWindow" id="window1">
    <property name="visible">True</property>
    <signal name="destroy" handler="on_destroy"/>
    <child>
      <widget class="GtkLabel" id="label1">
        <property name="visible">True</property>
        <property name="label" translatable="yes">In publishing and graphic design, lorem ipsum[p][1][2] is the name given to commonly used placeholder text (filler text) to demonstrate the graphic elements of a document or visual presentation, such as font, typography, and layout. The lorem ipsum text, which is typically a nonsensical list of semi-Latin words, is a hacked version of a Latin text by Cicero, with words/letters omitted and others inserted, but not proper Latin[1][2] (see below: History and discovery). The closest English translation would be "pain itself" (dolorem = pain, grief, misery, suffering; ipsum = itself).</property>
        <property name="wrap">True</property>
      </widget>
    </child>
  </widget>
</glade-interface>

The Python code:

#!/usr/bin/python

import pygtk
import gobject
import gtk.glade

def wrapped_label_hack(gtklabel, allocation):
    print "In wrapped_label_hack"
    gtklabel.set_size_request(allocation.width, -1)
    # If you uncomment this, we get INFINITE LOOPING!
    # gtklabel.set_size_request(-1, -1)
    print "Leaving wrapped_label_hack"

class ExampleGTK:

    def __init__(self, filename):
        self.tree = gtk.glade.XML(filename, "window1", "Example")
        self.id = "window1"
        self.tree.signal_autoconnect(self)

        # Connect to the size-allocate signal
        self.get_widget("label1").connect("size-allocate", wrapped_label_hack)

    def on_destroy(self, widget):
        self.close()

    def get_widget(self, id):
        return self.tree.get_widget(id)

    def close(self):
        window = self.get_widget(self.id)
        if window is not None:
            window.destroy()
        gtk.main_quit()

if __name__ == "__main__":
    window = ExampleGTK("example.glade")
    gtk.main()

© Stack Overflow or respective owner

Related posts about pygtk