在动态GUI中从Gtk视口/滚动窗口中删除小部件 [英] Remove widget from Gtk viewport / scrolled window in dynamic GUI

查看:106
本文介绍了在动态GUI中从Gtk视口/滚动窗口中删除小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个GUI(GTK3的Python绑定),其中一个Gtk滚动窗口(来自Glade)可以包含不同的树视图.该程序启动时会显示一个空窗口,并且第一次在所有情况下都可以使用:

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 first time around everything works with:

 self.scrolled_window.add_with_viewport(treeview)
 self.main_window.show_all()

测试程序的图片(请参见下面的源代码):

Picture of the test program (see source below):

第二次出现以下错误:

(main.py:15905):Gtk-CRITICAL **:gtk_scrolled_window_add_with_viewport:断言'gtk_bin_get_child(GTK_BIN(child_widget))== NULL'失败

我认为我可能需要先清空视口或滚动窗口,但不知道该怎么做并且找不到任何文档.

I think that I might need to empty the viewport or scrolled window first, but don't know how that is done and can't find any documentation for it.

编辑:使用 self.scrolled_window.remove(self.scrolled_window.get_child())时,我看不到数据集,并且出现错误消息切换图层时.

When using self.scrolled_window.remove(self.scrolled_window.get_child()) I don't see the dataset at the start up and error messages appear when switching layers.

我再次更新了代码,因此示例数据从一开始就存在.

林间空地文件(test_project.glade):

The glade file (test_project.glade):

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
  <requires lib="gtk+" version="3.10"/>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <property name="default_width">440</property>
    <property name="default_height">250</property>
    <signal name="destroy" handler="on_window1_destroy" swapped="no"/>
    <child>
      <object class="GtkBox" id="box1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkScrolledWindow" id="scrolledwindow1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="shadow_type">in</property>
            <child>
              <placeholder/>
            </child>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkScrolledWindow" id="scrolledwindow2">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="shadow_type">in</property>
            <child>
              <placeholder/>
            </child>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkBox" id="box2">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkButton" id="add_layer">
                <property name="label" translatable="yes">add layer</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <signal name="clicked" handler="on_add_layer_clicked" swapped="no"/>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="add_data">
                <property name="label" translatable="yes">add data</property>
                <property name="name">add_data</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <signal name="clicked" handler="on_add_data_clicked" swapped="no"/>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

python代码:

#!/usr/bin/python3

from gi.repository import Gtk
import random

class BottomTreeView(Gtk.TreeView):
    def __init__(self, store):
        Gtk.TreeView.__init__(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 = 0

        self.topstore = Gtk.TreeStore(str, object)
        self.topview = Gtk.TreeView(self.topstore)
        renderer1 = Gtk.CellRendererText()
        column1 = Gtk.TreeViewColumn("Name", renderer1, text=0)
        self.topview.append_column(column1)
        self.sw1.add_with_viewport(self.topview)

        #Adding test data in a dumb way
        self.store1 = Gtk.TreeStore(str)
        for x in range(10):
            self.store1.append(None, [str(random.random())])
        self.view1 = Gtk.TreeView(self.store1)
        self.rend1 = Gtk.CellRendererText()
        self.col1 = Gtk.TreeViewColumn("Dataset", self.rend1, text=0)
        self.view1.append_column(self.col1)
        self.sw2.add_with_viewport(self.view1)
        self.topstore.append(None, ["Layer 1", self.view1])

        self.store2 = Gtk.TreeStore(str)
        for x in range(10):
            self.store2.append(None, [str(random.random())])
        self.view2 = Gtk.TreeView(self.store2)
        self.rend2 = Gtk.CellRendererText()
        self.col2 = Gtk.TreeViewColumn("Dataset", self.rend2, text=0)
        self.view2.append_column(self.col2)
        self.topstore.append(None, ["Layer 2", self.view2])

        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):
        self.layernumber += 1
        store = Gtk.TreeStore(str)
        bottom = BottomTreeView(store)
        self.topstore.append(None, [str(self.layernumber), bottom])

    def on_add_data_clicked(self, widget):
        self.selection = self.topview.get_selection()
        model, treeiter = self.selection.get_selected()
        print("Adding data to {0}".format(model[treeiter][0]))
        datasheet = model[treeiter][1]
        datasheet.store.append(None, [str(random.random())])

    def on_window1_destroy(self, widget):
        Gtk.main_quit()

    def on_tree_selection_changed(self, selection):
        print("\n>>> Selection changed")
        model, treeiter = selection.get_selected()
        print(">>> Model: {0}, Treeiter: {1}".format(model, treeiter))
        if treeiter != None:
             print(">>> You selected Layer {0}.".format(model[treeiter][1]))
             tree_obj = model[treeiter][1]
             #The following lines mess up the program from the startup
             #self.sw2.remove(self.sw2.get_child())
             #self.sw2.add_with_viewport(tree_obj)
             #self.main_window.show_all()

def main():
    builder = Gtk.Builder()
    objects = builder.add_objects_from_file("test_project.glade",
         ("window1", ""))

    window_instance = MainWindow(builder)
    builder.connect_signals(window_instance)
    Gtk.main()

if __name__ == "__main__":
     main()

推荐答案

要清除滚动窗口,请执行以下操作:

To clear out the scrolled window, do this:

self.scrolled_window.remove(self.scrolled_window.get_child())

这篇关于在动态GUI中从Gtk视口/滚动窗口中删除小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆