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()
Here's a one-line variation on killown's solution:
label.connect('size-allocate', lambda label, size: label.set_size_request(size.width - 1, -1))
The above will make sure that the label takes on the width allocated to it, so that word-wrapping is happy.
Not sure why there's a "-1" for the width, but it seems harmless!
VMware's libview has a widget called WrapLabel which should do what you want, but it's in C++. A Python translation is available in the Meld repository (separated out from busybox.py).
example for resize and wrap the label dynamically:
EDIT:
import gtk
class DynamicLabel(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.set_title("Dynamic Label")
self.set_size_request(1, 1)
self.set_default_size(300,300)
self.set_position(gtk.WIN_POS_CENTER)
l = gtk.Label("Dynamic Label" * 10)
l.set_line_wrap(True)
l.connect("size-allocate", self.size_request)
vbox = gtk.VBox(False, 2)
vbox.pack_start(l, False, False, 0)
self.add(vbox)
self.connect("destroy", gtk.main_quit)
self.show_all()
def size_request(self, l, s ):
l.set_size_request(s.width -1, -1)
DynamicLabel()
gtk.main()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With