Marco Islas

Wrap text in a TreeView column

In ICT Consulting I did a small program that help the support team to create new tickets in the tracking system and keep them updated. In the "update" screen, I put a TreeView to show the comments history.

For Gtk TreeViews are just a "viewer" of the data stored in the "model", but it depends in the way the cell renderer will do its job. The render for text is called.. yes, you guessed: CellRendererText. This item will render the text as it is in the model.

If you are using text with markup (with the pango markup) it will be displayed with bold, italic and many other properties you define in your markup. But this render have a small problem, if you have a long line because the input method was a text box and the user didn't use the return key then you will end with a very very long line in the treeview.

If the line is not too big then the use of the scrollbar may help you, but, if that's not the case, and you or your user have to check more and more lines like that, using the scrollbar is tedious.

The fix: make the column usually big to wrap the text.

The trick is know the size of the window, and compute the space left by other columns then, set the
wrap_width property of the cell renderer according to the space left. That's what the "resize_wrap" function do.

treeview resize

This code may help you:

#!/usr/bin/env python
# -*- encoding: latin-1 -*-
# -*- coding: latin-1 -*-
import gtk
import pango
def resize_wrap(scroll, allocation, treeview, column, cell):
        otherColumns = (c for c in treeview.get_columns() if c != column)
        newWidth = allocation.width - sum(c.get_width() for c in otherColumns)
        newWidth -= treeview.style_get_property("horizontal-separator") * 4
        if cell.props.wrap_width == newWidth or newWidth <= 0:
        if newWidth < 300:
                newWidth = 300
        cell.props.wrap_width = newWidth
        column.set_property('min-width', newWidth + 10)
        column.set_property('max-width', newWidth + 10)
        store = treeview.get_model()
        iter = store.get_iter_first()
        while iter and store.iter_is_valid(iter):
                store.row_changed(store.get_path(iter), iter)
                iter = store.iter_next(iter)
window = gtk.Window()
window.connect('destroy', gtk.main_quit)
scroll = gtk.ScrolledWindow()
scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
model = gtk.ListStore(str)
text = '''
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
treeview = gtk.TreeView(model)
render = gtk.CellRendererText()
column = gtk.TreeViewColumn('Wrapped column', render, text = 0)
scroll.connect_after('size-allocate', resize_wrap, treeview, column, render)
blog comments powered by Disqus