Remove widget from Gtk viewport / scrolled window in dynamic GUI

前端 未结 2 1359
猫巷女王i
猫巷女王i 2021-01-17 00:35

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

2条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-17 01:34

    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.

    Working example

    I cleaned up the example from above and it is now fully functioning:

    Glade file

    
    
    
      
      
        False
        800
        600
        
        
          
            True
            False
            vertical
            
              
                True
                False
                
                  
                    True
                    True
                    in
                    
                      
                    
                  
                  
                    True
                    True
                    0
                  
                
                
                  
                    True
                    True
                    in
                    
                      
                    
                  
                  
                    True
                    True
                    1
                  
                
              
              
                True
                True
                0
              
            
            
              
                True
                False
                
                  
                    add layer
                    True
                    True
                    True
                    
                  
                  
                    False
                    True
                    0
                  
                
                
                  
                    add data
                    add_data
                    True
                    True
                    True
                    
                  
                  
                    False
                    True
                    1
                  
                
              
              
                False
                True
                1
              
            
          
        
      
    
    

    Python file

    #!/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()
    

提交回复
热议问题