2

I am trying to set a height limit for a GtkTreeView and want to use a scroll bar if the row data exceeds this limit. Currently, the whole window grows without limits and goes offscreen at some point. What is needed to get the desired behaviour?

My Python code (which simply adds a new row to the list store on every button click):

#!/usr/bin/env python3

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

class MyApp:

    def on_window1_destroy(self, obj, data=None):
        Gtk.main_quit()

    def button1_clicked(self, object):
        liststore = self.builder.get_object("liststore1")
        print(self.window.get_default_size())
        liststore.append(("test",))

    def __init__(self):
        self.builder = Gtk.Builder()
        self.builder.add_from_file("table_test.glade")
        self.builder.connect_signals(self)
        self.window = self.builder.get_object("window1")
        self.window.show()

if __name__ == "__main__":
    main = MyApp()
    Gtk.main()

The corresponding Glade file (test_table.glade):

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
  <requires lib="gtk+" version="3.12"/>
  <object class="GtkListStore" id="liststore1">
    <columns>
      <!-- column-name column1 -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <property name="resizable">False</property>
    <property name="default_height">300</property>
    <signal name="destroy" handler="on_window1_destroy" swapped="no"/>
    <child>
      <object class="GtkGrid" id="grid1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkButton" id="button1">
            <property name="label" translatable="yes">add</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <signal name="clicked" handler="button1_clicked" swapped="no"/>
          </object>
          <packing>
            <property name="left_attach">1</property>
            <property name="top_attach">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkTreeView" id="treeview1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="model">liststore1</property>
            <child internal-child="selection">
              <object class="GtkTreeSelection" id="treeview-selection1"/>
            </child>
            <child>
              <object class="GtkTreeViewColumn" id="treeviewcolumn1">
                <property name="title" translatable="yes">test-column</property>
                <child>
                  <object class="GtkCellRendererText" id="cellrenderertext1"/>
                  <attributes>
                    <attribute name="text">0</attribute>
                  </attributes>
                </child>
              </object>
            </child>
          </object>
          <packing>
            <property name="left_attach">0</property>
            <property name="top_attach">0</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
epR8GaYuh
  • 311
  • 9
  • 21

1 Answers1

2

You don't need to implement that widget, it already exists and its called Gtk.ScrolledWindow. The scrollbar behaviour can be automatic (only shows when the content exceeds the allocated space).

This can be achieved by adding a parent widget to the GtkTreeView you added via glade.

If you don't want the button to expand proportionally with the window then you should set the GtkButton vertical alignment as Start (also in glade).

Here follows your glade file with the added Gtk.ScrolledWindow:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.19.0 -->
<interface>
  <requires lib="gtk+" version="3.12"/>
  <object class="GtkListStore" id="liststore1">
    <columns>
      <!-- column-name column1 -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <property name="default_height">300</property>
    <signal name="destroy" handler="on_window1_destroy" swapped="no"/>
    <child>
      <object class="GtkGrid" id="grid1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="hexpand">True</property>
        <property name="vexpand">True</property>
        <child>
          <object class="GtkButton" id="button1">
            <property name="label" translatable="yes">add</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="halign">center</property>
            <property name="valign">start</property>
            <signal name="clicked" handler="button1_clicked" swapped="no"/>
          </object>
          <packing>
            <property name="left_attach">1</property>
            <property name="top_attach">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkScrolledWindow" id="scrolledwindow1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <property name="shadow_type">in</property>
            <child>
              <object class="GtkTreeView" id="treeview1">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="model">liststore1</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                </child>
                <child>
                  <object class="GtkTreeViewColumn" id="treeviewcolumn1">
                    <property name="title" translatable="yes">test-column</property>
                    <child>
                      <object class="GtkCellRendererText" id="cellrenderertext1"/>
                      <attributes>
                        <attribute name="text">0</attribute>
                      </attributes>
                    </child>
                  </object>
                </child>
              </object>
            </child>
          </object>
          <packing>
            <property name="left_attach">0</property>
            <property name="top_attach">0</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

The result should be similar to this:

enter image description here

José Fonte
  • 4,016
  • 2
  • 16
  • 28
  • 1
    I already had tried to wrap the tree view into a scrolled window, but did not set the values for `hexpand` and `vexpand` leading to an error message ("In pixman_region32_init_rect: Invalid rectangle passed"). Now it works. – epR8GaYuh Feb 01 '18 at 16:28