如何在 GTK4 (>= 4.10) 中构建树

Dor*_*mon 6 gtk gtkmm gtk4

正如文档所说,GTK4 中的 TreeView自 4.10 起已被弃用。推荐的替代品是 ColumnView。但是,我找不到关于如何通过 ColumnView 在 GTK4 中构建类似树状视图的小部件的明确文档或示例。我发现可能TreeExpander与它有关,但我仍然不知道如何处理它。

Jer*_*ten 3

我所做的一个非常简短的概述:

  1. 熟悉新的动态列表小部件(Gtk.GridView 和 Gtk.ColumnView)如何适用于平面模型(GLib.ListStore)。演示应用程序中有示例代码。
  2. 创建一个 Gtk.TreeListModelCreateModelFunc 函数,该函数将模型项作为参数,如果该项有子项(例如,是文件系统模型中的文件夹),则创建并返回 Gtk.ListStore 来保存子项。如果子项已经可用,那么它们也可以在此处附加到子模型中。这意味着无论行是否展开,子项都会被预加载。出于启动性能的原因,您可能希望安排在行实际扩展时加载它们,这比较困难 - 在这种情况下,您必须向模型添加一个虚拟子级,否则扩展器将不会显示。
  3. 创建一个 Gtk.SignalListItemFactory。
  4. setup处理程序中,像往常一样创建一个显示小部件,然后不使用显示小部件作为 Gtk.ListItem 的子项,而是创建一个 Gtk.TreeExpander,并将其作为 Gtk.ListItem 的子项,并使显示小部件作为 Gtk.ListItem 的子项。扩展器。
  5. bind处理程序中,从提供的对象中获取显示小部件和模型项。这里的一个复杂之处是该对象可能是一个 Gtk.TreeListRow,其项目可能是另一个 Gtk.TreeListRow,因此获取模型项目更加困难。像往常一样将小部件绑定到模型项。然后从 Gtk.ListItem 位置获取 Gtk.TreeListRow 并list-row为其设置扩展器的属性。
  6. 如果您延迟加载子项,那么您将需要检测该行何时首次展开。您可以连接到notify该属性的信号Gtk.TreeListRow.expanded来执行此操作。
  7. 使用带有 GLib.ListStore 的 Gtk.TreeListModel 作为root_storeGtk.ColumnView 的模型(像往常一样包装在 Gtk.SelectionModel 之后)。您必须passthrough将该属性设置为,false否则不会出现扩展器。如果您按需加载子项目,那么autoexpand也应该如此false
  8. 如果您使用具有多列的 Gtk.ColumnView,则只需将扩展器添加到第一列。否则,工厂信号处理程序或类似于平面模型,但bind处理程序需要适应 Gtk.TreeListRow 参数。

简化和性能改进很可能是可能的,或者 Gtk4 的更高版本可能会引入一些便利性以使其不那么繁琐。

我正在使用上述策略开发文件浏览器实现,目前位于https://github.com/elementary/files/tree/gtk4-treelistmodel,但这可能会合并到其他分支(或放弃!)。请注意,该分支正在开发中,包含未解决的错误,但项目的显示正常。