GtkColumnView

在我最近关于GTK 4中列表视图模型的系列文章中,我留下了一个未完成的部分,那就是详细介绍GtkColumnView。 这将是该系列中最复杂的部分。 我们正在进入GtkTreeView的核心地带——任何旨在取代其大部分功能的都将是一个复杂的野兽。

概述

就像我们对GtkListView所做的那样,我们将从一个高层次的概述和一个图片开始。

如果你回顾一下列表视图的图片,你会记得我们使用列表项工厂为模型中需要显示的每个项目创建一个小部件。

在列视图中,我们需要为每个项目创建多个小部件——每列一个。 我们通过为每列提供自己的列表项工厂来实现这一点。 每当我们需要显示一个新项目时,我们将来自每列工厂的小部件组合成新项目的一行。

在内部,列视图实际上是使用列表视图来保存行。 这很好,因为我之前关于项目重用以及如何使用列表项工厂的帖子中解释的所有内容都同样适用。

当然,有些事情是不同的。 例如,列视图必须组织大小分配,以便所有行中的小部件对齐以形成正确的列。

注意:与 GtkListView 一样,列视图仅为当前视图中的模型部分创建小部件,因此它具有相同的垂直可伸缩性。 在水平方向上则并非如此——每一行都完全填充了每个列的小部件,即使它们在左侧或右侧视图之外。 因此,如果添加大量列,速度会变慢。

标题和其他复杂情况

列对象还包含其他数据,例如标题。 列视图使用这些数据为每列显示标题。 如果将列视图标记为可重新排序,则可以通过拖放标题小部件来重新排列列。 如果将列标记为可调整大小,则可以拖动两列之间的边框来调整它们的大小。

如果你注意到了,你现在可能会想知道这种调整大小如何与这样一个事实相联系,即行中的单元格可以是任意小部件,这些小部件希望至少有其最小尺寸可用于绘制其内容。 答案是我们正在使用GTK 4渲染机制的另一个新功能:小部件可以控制如何处理在其边界之外(通过子小部件)绘制的内容,即

 gtk_widget_set_overflow (cell, GTK_OVERFLOW_HIDDEN)

排序、选择和对 treeview 对等性的追求

由于我们希望在功能上与GtkTreeview相匹配,所以我们还没有完成。 用户喜欢在树视图中做的另一件事是单击标题,按该列对内容进行排序。 GtkColumnView 标题也允许这样做。

你可能从上一篇文章中记得,排序是通过将数据包装在GtkSortListModel中,并为其提供合适的排序器对象来完成的。 由于我们希望根据单击的列标题具有不同的排序顺序,因此我们为每列提供了自己的排序器,可以使用以下方式设置:

gtk_column_view_column_set_sorter (column, sorter)

但是,我们如何从刚刚单击的列中获取正确的排序器,并将其附加到排序模型? 请记住,排序模型不是我们要传递给列视图的最外层模型,因为它始终是一个选择模型,因此列视图不能自己切换排序列表模型上的排序器。

我们提出的解决方案是使列视图提供一个在内部使用列排序器的排序器,使用以下方式:

gtk_column_view_get_sorter (view)

你可以在设置模型时将此排序器提供给排序模型一次,然后在用户单击列标题以激活不同的列排序器时,事情将自动更新。

这听起来很复杂,但效果出奇地好。 这种方法的一个好处是,我们实际上可以一次按多个列排序——因为我们拥有所有可用的列排序器,并且我们知道你最后单击了哪个。

相比之下,选择处理很容易。 它与 GtkListView 中的工作方式相同。

总结

GtkColumnView 是一个复杂的小部件,但我希望这一系列文章能让你更容易开始使用它。