<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Programming on dev@iostream.pl</title><link>https://dev.iostream.pl/categories/programming/</link><description>Recent content in Programming on dev@iostream.pl</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sun, 28 Jun 2026 16:08:00 +0200</lastBuildDate><atom:link href="https://dev.iostream.pl/categories/programming/index.xml" rel="self" type="application/rss+xml"/><item><title>2026-06-28</title><link>https://dev.iostream.pl/posts/2026-06-28/</link><pubDate>Sun, 28 Jun 2026 16:08:00 +0200</pubDate><guid>https://dev.iostream.pl/posts/2026-06-28/</guid><description>&lt;h1 id="listbox-anyone"&gt;Listbox, anyone?
&lt;/h1&gt;&lt;p&gt;Many popular UI toolkits have their listbox control implemented to be as simple in use as possible. The most common operations are: creating the control, adding the data rows, deleting and editing data, handling the selection. Almost all toolkits provide single functions or suitable methods to realize above operations.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Gtk+&lt;/code&gt; is quite different: it requires more abstract way of thinking and additional objects to be created, but the lists and trees are more flexible and elegant.&lt;/p&gt;
&lt;h1 id="storing-the-data"&gt;Storing the data
&lt;/h1&gt;&lt;p&gt;Before we can display a single string, let&amp;rsquo;s first earn a PhD in data models.&lt;/p&gt;
&lt;p&gt;Unlike the the other toolkits, the gtk+ list allows to display a few values per a row. Gtk+ list also distinguishes between the types of data, while other lists treat its row data as a single string.&lt;/p&gt;
&lt;p&gt;In fact, the &lt;code&gt;TreeView&lt;/code&gt; widget will be used to display elements. The model lets the display widget know about data types to be used in the control, it also determines the type of the control (if it should be a list or a tree). Besides, the model is used to store all the data (it is common to find a &amp;ldquo;store&amp;rdquo; term instead of &amp;ldquo;model&amp;rdquo; in various papers or in someone&amp;rsquo;s code)&lt;/p&gt;
&lt;p&gt;A store/model can be created by calling a proper constructor with at least one data type (to be used in the list) as argument:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;store &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;ListStore(type1, &lt;span style="color:#f92672"&gt;...&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;store &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;ListStore(int, str, str)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Created store will contain one integer value and two strings per row. Although pygtk reference recommends to use build-in GObject types (for instance, gobject.TYPE_INT and gobject.TYPE_STRING instead of int and str respectively), python built-in types are also allowed (GObject names really matter in C or C++)&lt;/p&gt;
&lt;h1 id="adding-the-data-rows"&gt;Adding the data rows
&lt;/h1&gt;&lt;p&gt;The method append from Gtk.ListStore class allows to append one row at the end of the store. Sequence with all values should be passed as a parameter:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;store&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([val1, &lt;span style="color:#f92672"&gt;...&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;store&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#ae81ff"&gt;7&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;str1&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;str2&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="columns-and-renderers"&gt;Columns and renderers
&lt;/h1&gt;&lt;p&gt;Control widget should know about columns it should display, their order and how to present data from the store. Gtk+ provides the column widget (Gtk.TreeViewColumn) to manage displaying the cells of data and renderer widgets (Gtk.CellRenderer and its derivatives) to realize rendering of particular cells.&lt;/p&gt;
&lt;p&gt;Column widget is usually created by calling a constructor of &lt;code&gt;Gtk.TreeViewColumn&lt;/code&gt; with a header title passed as the argument:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeViewColumn(title)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeViewColumn(&lt;span style="color:#e6db74"&gt;&amp;#34;Column header&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Column header is visible by default — passing an empty string to the constructor will not get rid of it.&lt;/p&gt;
&lt;p&gt;Cell renderer should be one of &lt;code&gt;Gtk.CellRendererAccel&lt;/code&gt;, &lt;code&gt;Gtk.CellRendererCombo&lt;/code&gt;, &lt;code&gt;Gtk.CellRendererPixbuf&lt;/code&gt;, &lt;code&gt;Gtk.CellRendererProgress&lt;/code&gt;, &lt;code&gt;Gtk.CellRendererSpin&lt;/code&gt;, &lt;code&gt;Gtk.CellRendererText&lt;/code&gt;, &lt;code&gt;Gtk.CellRendererToggle&lt;/code&gt;. The renderer object is usually created by calling the constructor with no parameters&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;renderer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Renderers should be added to the column widgets: pack_start and pack_end methods are used to do the packing.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(renderer)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_end(renderer)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeViewColumn(&lt;span style="color:#e6db74"&gt;&amp;#34;Column1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;renderer1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;renderer2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;renderer3 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(renderer1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(renderer2)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_end(renderer3)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The column widget must know which data column from the model should be connected to any of these renderers. This could be done by calling set_attributes method:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(renderer, &lt;span style="color:#f92672"&gt;...&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All optional parameters are &amp;ldquo;key = value&amp;rdquo; pairs, where key is the data type and value is number of column in the store&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(renderer1, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(renderer2, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;column1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(renderer3, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="treeview-control"&gt;TreeView control
&lt;/h1&gt;&lt;p&gt;The last step is to create a control and add all columns. Constructor of the control takes the store as first parameter:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;listControl &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeView(model&lt;span style="color:#f92672"&gt;=&lt;/span&gt;store)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The method append_column adds given column to the tree/list control:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;listControl&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append_column(column)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Summary: at least, four objects should be created to have the tree/list control working: a model which determines types of data and stores all the rows, a renderer, which takes care of displaying the cells, a column, which glues together model columns and suitable renderers and a treeview control itself.&lt;/p&gt;
&lt;h1 id="working-examples"&gt;Working examples
&lt;/h1&gt;&lt;p&gt;Following examples illustrate the creation and displaying of the lists.&lt;/p&gt;
&lt;h2 id="very-simple-list-control"&gt;Very simple list control
&lt;/h2&gt;&lt;p&gt;The simplest list control contains only one column and displays only one value per row&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; gi
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gi&lt;span style="color:#f92672"&gt;.&lt;/span&gt;require_version(&lt;span style="color:#e6db74"&gt;&amp;#34;Gtk&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;3.0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; gi.repository &lt;span style="color:#f92672"&gt;import&lt;/span&gt; Gtk
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ListBoxViewer1&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;destroyCallback&lt;/span&gt;(self, widget, data&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;main_quit()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;ListStore(str)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 1&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 2&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 3&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 4&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 5&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeViewColumn(&lt;span style="color:#e6db74"&gt;&amp;#34;Sample column&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer, &lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mainWindow &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Window(type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;WindowType&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TOPLEVEL)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mainWindow&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_title(&lt;span style="color:#e6db74"&gt;&amp;#39;ListBoxViewer1&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listBox &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeView(model&lt;span style="color:#f92672"&gt;=&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listBox&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append_column(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mainWindow&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listBox)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mainWindow&lt;span style="color:#f92672"&gt;.&lt;/span&gt;connect(&lt;span style="color:#e6db74"&gt;&amp;#39;delete_event&amp;#39;&lt;/span&gt;, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;destroyCallback)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mainWindow&lt;span style="color:#f92672"&gt;.&lt;/span&gt;show_all()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__ &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; lbv1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ListBoxViewer1()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;main()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This example covers the theory of creating listboxes with additional routines necessary to run minimal gtk+ program. Additional method is added to provide termination of this example when its window has been closed.&lt;/p&gt;
&lt;p&gt;All list-related routines are explained below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;ListStore(str)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 1&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 2&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 3&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 4&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 5&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The model is created: it can hold one string value per a row. Then it is populated by 5 rows.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Text renderer is created.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeViewColumn(&lt;span style="color:#e6db74"&gt;&amp;#34;Sample column&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer, &lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A column is created. Then the renderer is packed into the column, and the column is informed which column and what type of data from the store will be used.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listBox &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeView(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listBox&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append_column(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Main widget is created. The column is appended to the list.&lt;/p&gt;
&lt;p&gt;It looks like the following:&lt;/p&gt;
&lt;p&gt;&lt;img alt="ListboxViewer 1" class="gallery-image" data-flex-basis="224px" data-flex-grow="93" height="333" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://dev.iostream.pl/posts/2026-06-28/listbox-1.png" width="312"&gt;&lt;/p&gt;
&lt;p&gt;Explanation of the next examples contains only the routines related to list control; other routines did not change if not mentioned.&lt;/p&gt;
&lt;h2 id="two-values-per-row"&gt;Two values per row
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;ListStore(str, int)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 1&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;18000&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 2&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1500&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 3&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;900&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 4&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;60&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 5&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now the store holds a string an integer pair per a row.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeViewColumn(&lt;span style="color:#e6db74"&gt;&amp;#34;Sample column&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_property(&lt;span style="color:#e6db74"&gt;&amp;#39;xalign&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A column and two cell renderers are created. The set_property routine with xalign property to be set tells the renderer to align right the values in the row. Value of 0.0 means left alignment, 0.5 centers the text and 1.0 means right alignment.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer, &lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer, &lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The two renderers are packed into the column. The string value renderer will expand the cell if possible. Proper renderers are assigned to proper data columns from the store.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listBox &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeView(store&lt;span style="color:#f92672"&gt;=&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listBox&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append_column(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The control is created and the column is appended to the control.&lt;/p&gt;
&lt;p&gt;The following picture shows the result of this example:&lt;/p&gt;
&lt;p&gt;&lt;img alt="ListboxViewer 2" class="gallery-image" data-flex-basis="265px" data-flex-grow="110" height="240" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://dev.iostream.pl/posts/2026-06-28/listbox-2.png" width="265"&gt;&lt;/p&gt;
&lt;h2 id="two-columns-in-the-control"&gt;Two columns in the control
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeViewColumn(&lt;span style="color:#e6db74"&gt;&amp;#34;Ascii text&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeViewColumn(&lt;span style="color:#e6db74"&gt;&amp;#34;Numeric value&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_property(&lt;span style="color:#e6db74"&gt;&amp;#39;xalign&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer, &lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer, &lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Every column packs one of the renderes. It looks like the following:&lt;/p&gt;
&lt;p&gt;&lt;img alt="ListboxViewer 3" class="gallery-image" data-flex-basis="222px" data-flex-grow="92" height="219" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://dev.iostream.pl/posts/2026-06-28/listbox-3.png" width="203"&gt;&lt;/p&gt;
&lt;h2 id="adding-pixmaps-to-the-list"&gt;Adding pixmaps to the list
&lt;/h2&gt;&lt;p&gt;Now, creating the store is like below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sheetIcon &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;gdk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pixbuf_new_from_file(&lt;span style="color:#e6db74"&gt;&amp;#34;sheet.xpm&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;ListStore(str, int, Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;gdk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Pixbuf)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 1&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;18000&lt;/span&gt;, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sheetIcon])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 2&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1500&lt;/span&gt;, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sheetIcon])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 3&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;900&lt;/span&gt;, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sheetIcon])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 4&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;60&lt;/span&gt;, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sheetIcon])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listStore&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append([&lt;span style="color:#e6db74"&gt;&amp;#34;String 5&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sheetIcon])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The pixbuf is added in every row. Of course, it may be different in every row. This is only the example.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;iconRenderer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererPixbuf()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The icon requires a special kind of cell renderer.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;iconRenderer, &lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;iconRenderer, pixbuf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pixbuf cell renderer is now packed into the first column together with the text renderer.&lt;/p&gt;
&lt;p&gt;It looks like the following:&lt;/p&gt;
&lt;p&gt;&lt;img alt="ListboxViewer 4" class="gallery-image" data-flex-basis="125px" data-flex-grow="52" height="465" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://dev.iostream.pl/posts/2026-06-28/listbox-4.png" width="244"&gt;&lt;/p&gt;
&lt;h2 id="display-the-same-values-twice-or-more-times"&gt;Display the same values twice or more times
&lt;/h2&gt;&lt;p&gt;Displaying more values per row is achieved by multiplicating the renderes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeViewColumn(&lt;span style="color:#e6db74"&gt;&amp;#34;Ascii text&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;TreeViewColumn(&lt;span style="color:#e6db74"&gt;&amp;#34;Numeric value&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer3 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererText()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;iconRenderer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererPixbuf()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;iconRenderer2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Gtk&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CellRendererPixbuf()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_property(&lt;span style="color:#e6db74"&gt;&amp;#39;xalign&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_property(&lt;span style="color:#e6db74"&gt;&amp;#39;xalign&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_property(&lt;span style="color:#e6db74"&gt;&amp;#39;xalign&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.5&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_property(&lt;span style="color:#e6db74"&gt;&amp;#39;xalign&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;iconRenderer, &lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer, &lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer, &lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer2, &lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;iconRenderer2, &lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer3, &lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pack_start(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer2, &lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;iconRenderer, pixbuf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer2, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;numRenderer3, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textRenderer2, text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listColumn2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;set_attributes(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;iconRenderer2, pixbuf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Also, the left, right and center alignment of text is shown.&lt;/p&gt;
&lt;p&gt;It looks like the following:&lt;/p&gt;
&lt;p&gt;&lt;img alt="ListboxViewer 5" class="gallery-image" data-flex-basis="209px" data-flex-grow="87" height="511" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://dev.iostream.pl/posts/2026-06-28/listbox-5.png" width="447"&gt;&lt;/p&gt;</description></item></channel></rss>