I am building a GUI (Python binding of GTK3) where one Gtk Scrolled Window (from Glade) can contain different treeviews. The program launches with an empty window and the fi
After the answer by ptomato I realized that I was adding the TreeViews by using:
self.scrolled_window.add_with_viewport(some_treeview)
For some reason the scrolled_window.remove() function does not like viewports. Instead one should use:
self.scrolled_window.add(some_treeview)
It probably makes sense because the documentation states that:
If a widget has native scrolling abilities, such as Gtk.TextView, Gtk.TreeView or Gtk.IconView, it can be added to a Gtk.ScrolledWindow with Gtk.Container.add (). If a widget does not, you must first add the widget to a Gtk.Viewport, then add the viewport to the scrolled window.
(Source: https://lazka.github.io/pgi-docs/Gtk-3.0/classes/Viewport.html)
So because a Gtk.TreeView is already scrollable it should not go into a separate Gtk.Viewport widget.
I cleaned up the example from above and it is now fully functioning:
#!/usr/bin/python3
from gi.repository import Gtk
import random
class LayerTreeView(Gtk.TreeView):
def __init__(self, store):
Gtk.TreeView.__init__(self, store)
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Name", renderer, text=0)
self.append_column(column)
class DataTreeView(Gtk.TreeView):
def __init__(self, store):
Gtk.TreeView.__init__(self, store)
self.store = store
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Dataset", renderer, text=0)
self.append_column(column)
for x in range(10):
self.store.append(None, [str(random.random())])
class MainWindow(object):
def __init__(self, builder):
self.main_window = builder.get_object("window1")
self.sw1 = builder.get_object("scrolledwindow1")
self.sw2 = builder.get_object("scrolledwindow2")
self.layernumber = 1
#Initializing top TreeStore and TreeView
#First object is the store, second is the view of the bottom data-view
self.topstore = Gtk.TreeStore(str, object, object)
self.topview = LayerTreeView(self.topstore)
self.sw1.add(self.topview)
#Adding some testdata
for x in range(3):
datastore = Gtk.TreeStore(str)
dataview = DataTreeView(datastore)
layername = "Layer {0}".format(self.layernumber)
self.layernumber += 1
self.topstore.append(None, [layername, datastore, dataview])
self.select = self.topview.get_selection()
self.select.connect("changed", self.on_tree_selection_changed)
self.main_window.show_all()
def on_add_layer_clicked(self, widget):
datastore = Gtk.TreeStore(str)
dataview = DataTreeView(datastore)
layername = "Layer {0}".format(self.layernumber)
self.layernumber += 1
self.topstore.append(None, [layername, datastore, dataview])
def on_add_data_clicked(self, widget):
self.selection = self.topview.get_selection()
model, treeiter = self.selection.get_selected()
if treeiter != None:
data_object = model[treeiter][1]
data_object.append(None, [str(random.random())])
def on_window1_destroy(self, widget):
Gtk.main_quit()
def on_tree_selection_changed(self, selection):
model, treeiter = selection.get_selected()
if treeiter != None:
treeview_object = model[treeiter][2]
child = self.sw2.get_child()
if child != None:
self.sw2.remove(self.sw2.get_child())
self.sw2.add(treeview_object)
self.main_window.show_all()
def main():
builder = Gtk.Builder()
objects = builder.add_objects_from_file("treeview_switcher.glade",
("window1", ""))
window_instance = MainWindow(builder)
builder.connect_signals(window_instance)
Gtk.main()
if __name__ == "__main__":
main()