GTK 中的延迟加载列表视图#

2024-04-09

我希望通过 GTK# 中的列表视图显示大型数据集,而性能是这里的一个问题。我目前正在使用由 ListStore 支持的 TreeView,但将所有数据添加到 ListStore 需要很长时间。 GTK 中是否有某种支持延迟加载数据的列表视图小部件?在 Winforms 中,您可以使用 DataGridView 的 VirtualMode 属性来处理此问题,但我没有看到 GTK 的任何此类内容。


据我所知,没有任何小部件可以在 Gtk 中执行您想要的操作,但是,您可以在最终结果中执行与 TreeView 中的 VirtualMode 属性类似的操作。

TreeView 控件的问题在于它会提前从其模型中获取所有数据。如果不是这样,那么我会建议仅使用模型方法来解决这个问题,但不幸的是,TreeView 在获取数据时是贪婪的,因此需要控制何时从视图加载数据,否则它会怎样能够判断行何时可见,从而通知模型或代理在行变得可见时获取该行的数据。

你需要做三件事才能让它发挥作用

1) 在树视图中使用的模型,最初具有所有行,但任何字段中没有数据
2)从您使用的任何数据库中获取数据的方法
3) 确定要获取哪些行数据的方法

前两项可以在模型级别完成。确定要获取哪些行需要 Treeview 小部件以及确定显示哪些行的方法。我下面使用的方法不是最佳的,但它确实有效,并且可以根据您想要的任何用途进行整理和/或调整。

我使用代理类存储在模型中,用于获取特定于该行的数据。在我的示例中,它称为 ProxyClass。它获取并保存一行数据,该数据最初为空。在这种情况下,Fetch 方法只是创建并返回一个字符串“some data”+ id

这将保存在 MyNode 的实例中,该实例继承自 TreeNode,表示一行数据。第一列返回代理中保存的数据,第二列(从未显示)保存代理类实例。

然后,您创建 NodeStore、模型,并用 MyNode(id) 的实例填充它,如下面的示例所示。

数据加载时间的控制由 CellDataFunc 控制。这个方法是让它发挥作用的关键。 CellDataFunc 负责设置 CellRendererText 中由传递给它的迭代器标识的行中特定列的文本。每次树视图显示一行时都会调用它,并且仅针对新显示的行。因此,只会获取显示中呈现的单元格的数据。这为您提供了一种控制何时获取数据的方法,从而仅在需要时才获取数据。

您可以使 TreeView 使用 CellDataFunc 根据需要加载数据,方法是使用 TreeViewColumn.SetCellDataFunc 将数据应用到其中一列。您只需在一列上执行此操作,因为它可以获取整行的数据。

要阻止除可见行之外的所有行获取其数据,可以通过检查当前单元格是否在可见范围内来完成。为此,您可以调用 TreeView.GetVisibleRange(out start,out end) 然后查看传递给该函数的当前迭代器是否在 start 和 end range 内,它们是 TreePath 对象,因此需要首先将它们更改为 TreeIters。 Model.GetIter(out iter_start, 开始)。然后检查 iter.UserData.ToInt32() >= iter_start.UserData.ToInt32() 是否小于 iter_end。如果当前iter落在iter_start到iter_end的范围内,则获取数据,否则保留它。

这是我的例子。

代理类

namespace LazyTree
{

    public class ProxyClass 
    {
      int id;
      string data;

      public ProxyClass (int id)
      {
        this.id = id;
        data = null;
      }


      public void Fetch()
      {
        data = "some data " + id;
      }


      public int Id
      {
        get { return id; }
      }

      public string Data
      {
        get {return data;}
      }
  }
}

自定义 TreeNode 实例

namespace LazyTree
{
    [Gtk.TreeNode (ListOnly=true)]
    public class MyNode : Gtk.TreeNode
    {
        protected ProxyClass proxy;

        public MyNode (int id)
        {
            proxy = new ProxyClass(id);
        }

        [Gtk.TreeNodeValue (Column=1)]
        public ProxyClass Proxy
        {
            get {return proxy;}
        }

        [Gtk.TreeNodeValue (Column=0)]
        public string Data
        {
            get { return proxy.Data; }
        }
    }
}

窗口包括滚动窗口和树视图。这也是定义 CellDataFunc 的地方,尽管它可以放在任何地方。

namespace LazyTree
{

    public class MyWindow : Gtk.Window
    {
        int NUMBER_COLUMNS = 10000;
        Gtk.NodeStore store;
        Gtk.NodeStore Store {
            get {
                if (store == null) {
                    store = new Gtk.NodeStore (typeof (MyNode));
                    for(int i = 0; i < NUMBER_COLUMNS; i++)
                    {
                        store.AddNode (new MyNode (i));
                    }
                }
                return store;
            }
        }


        protected void CellDataFunc(Gtk.TreeViewColumn column,
                                    Gtk.CellRenderer cell,
                                    Gtk.TreeModel model,
                                    Gtk.TreeIter iter)
        {
            try {
                string data = (string)model.GetValue(iter, 0);
                ProxyClass proxy = (ProxyClass)model.GetValue(iter, 1);
                Gtk.TreeView view = (Gtk.TreeView)column.TreeView;
                Gtk.TreePath start, end;
                bool go = view.GetVisibleRange(out start,out end);
                Gtk.TreeIter iter_start, iter_end;
                if(go)
                {
                    model.GetIter(out iter_start, start);
                    model.GetIter(out iter_end, end);
                }
                if (go &&
                    data == null && 
                    iter.UserData.ToInt32() >= iter_start.UserData.ToInt32() &&
                    iter.UserData.ToInt32() <= iter_end.UserData.ToInt32())
                {
                    Console.WriteLine("Lazy Loading " + proxy.Id + ", Visible: " + cell.Visible);
                    proxy.Fetch();
                }

                ((Gtk.CellRendererText)cell).Text = data;
            } catch(Exception e) {
                Console.WriteLine("error: " + e);
            }
        }


        public MyWindow () : base("Lazy Tree")
        {
            Gtk.NodeView view = new Gtk.NodeView(Store);

            Gtk.ScrolledWindow scroll = new Gtk.ScrolledWindow();
            scroll.Add(view);
            Add(scroll);
            Gtk.CellRendererText cell = new Gtk.CellRendererText ();
            view.AppendColumn ("Lazy Data", cell, "text", 0);

            Gtk.TreeViewColumn column = view.GetColumn(0);

            column.SetCellDataFunc(cell, CellDataFunc);
        }


        protected override bool OnDeleteEvent (Gdk.Event ev)
        {
            Gtk.Application.Quit ();
            return true;
        }

        public static void Main()
        {
            Gtk.Application.Init ();
                MyWindow win = new  MyWindow();
            win.SetDefaultSize(200, 200);
                    win.ShowAll ();
            Gtk.Application.Run ();
        }
    }


}

希望这就是你的追求。

请参阅 c 文档以更好地解释每个方法及其参数的作用。 Mono 文档还有很多不足之处。

SetCellDataFunc(C 文档)http://developer.gnome.org/gtk/stable/GtkTreeViewColumn.html#gtk-tree-view-column-set-cell-data-func http://developer.gnome.org/gtk/stable/GtkTreeViewColumn.html#gtk-tree-view-column-set-cell-data-func

(CeCellDataFunc)http://developer.gnome.org/gtk/stable/GtkTreeViewColumn.html#GtkTreeCellDataFunc http://developer.gnome.org/gtk/stable/GtkTreeViewColumn.html#GtkTreeCellDataFunc

(销毁函数)http://developer.gnome.org/glib/unstable/glib-Datasets.html#GDestroyNotify http://developer.gnome.org/glib/unstable/glib-Datasets.html#GDestroyNotify

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GTK 中的延迟加载列表视图# 的相关文章

随机推荐

  • 如何在 Struts 2 的单个视图中使用多个表单/操作

    我有一个显示在每个页面上的搜索框 搜索框的 JSP 代码通过图块插入到每个页面中 搜索框有一个表单和一个操作类SearchAction它需要为下拉框预加载一些属性 这SearchAction类有一个input 方法 它执行此初始化 一些页面
  • VS2010 调试/分析时的性能差异

    请参阅编辑 底部 问题可能不是我最初想的 Hi All 我正在编写一个图形库 它可以处理许多滤镜 效果 包括模糊 我一直在尝试优化我的代码 但遇到了一些我不明白的东西 当我运行代码时without在性能向导中 小图像上的简单 3x3 模糊可
  • 在Android应用程序中使用DIAL协议

    我想在我的视频流应用程序中使用 DIAL 协议 我的应用程序是一个示例应用程序 仅使用 VideoView 播放 HLS 示例流 我想集成 DIAL 协议 http www dial multiscreen org http www dia
  • servlet 代码中类型信息丢失

    我有一个与 Jersey 一起使用的简单闪存实现 如下所示 PostConstruct def before flash rotateIn PreDestroy def after flash rotateOut object flash
  • 如何在 XCode5+ 中创建 Interface Builder 插件?

    我需要做一个对象库 一个 Interface Builder 插件 例如Mapkit这样用户就可以拖动我的自定义对象并添加到UIView 作为属性 我想用我的基本属性来显示和配置它 知道如何做到这一点吗 thanks 在 Xcode 4 0
  • 通过javascript设置iframe的useragent

    试图满足的业务需求 在 iframe 中加载现有页面 模拟 iPhone 用户代理 这需要在客户端发生的原因是 有客户端脚本它检测用户代理并将一些类附加到 html 元素上 基于此 站点的样式将发生根本性的变化 因为 CSS 的目标元素是基
  • DBMS_RANDOM 被认为是危险的吗?

    我们的数据库团队希望从 PUBLIC 撤销 DBMS RANDOM 上的执行 以解决安全问题 如果你用谷歌搜索它 一些安全专家会认为这个包很危险 但没有说出原因 Ingram 和 Shaul 的书 Practical Oracle Secu
  • Android 4.4.4 上的改造 SSL 错误

    我们有一个现有的 Android 应用程序 它使用 Retrofit 连接到服务器并发送和接收 JSON 自从将我的设备更新到 Android 4 4 4 后 我在尝试连接时收到以下错误 D Retrofit 8004 javax net
  • Android Volley ECONNRESET

    我尝试使用Volley库并将图像上传到服务器 该库应该在独立模式下执行此过程 但出现以下错误消息 java net SocketException 发送失败 ECONNRESET 连接重置 由同行 是否可能是服务器端配置错误 我尝试上传一个
  • 不需要时禁用 R Shiny 中的 selectInput

    我正在构建一个shiny网页由两个表单组成selectInput 第一个 静态 在ui部分和第二部分 动态 在server部分 实际问题的简化如下所示 require shiny ui lt fluidPage The static inp
  • 防止“删除和更新”firebase中的子项

    我发现没有办法设置安全规则来防止孩子的 删除和更新 write data exists newData exists newData exists 那没有道理 为了便于将来参考 Firebase 控制台允许您测试数据库安全规则 以便您可以在
  • EF 7 迁移到现有数据库

    我正在使用 ASP Net 5 和 EF7 开发一个 Web 项目 我已将现有数据库中的所有表导入到项目中的模型中 但是 我在迁移方面遇到了问题 我已经创建了初始迁移 对特定实体进行了一些更改 在所做的更改之后创建了另一个迁移 现在想要在数
  • 快速排序可以在没有堆栈和递归的情况下用C实现吗?

    我找到了这个帖子如何在c中不使用堆栈进行迭代快速排序 https stackoverflow com questions 32388760 how to do iterative quicksort without using stack
  • 如何在powershell中获取对象属性的名称?

    我知道我可以使用 get member 来获取对象的所有属性 但我正在浏览对象列表 并且我对名称不断变化的最后一个属性感兴趣 为了自动化我的脚本 我试图获取最后一个属性的名称 但我不确定如何获取 假设我有 result get member
  • 如何在php脚本中加载Wordpress环境?

    如何在脚本中加载Wordpress环境 以便使用Wordpress的功能 我需要这个 因为我需要从异步执行的脚本中调用多个函数 您需要加载 wp load php 文件 然后该文件将允许您调用 WordPress 函数 例如 require
  • 安装和配置 xvfb

    我正在尝试找到兼容的 Ubuntu 操作系统 xorg 版本和 xvfb 版本 任何人都可以帮我指导安装 xvfb 而不需要挂断吗 初始化内置扩展 GLX 到目前为止我已经尝试过以下方法 Ubuntu 13 Server No graphi
  • 枚举在类体之外但在命名空间内的定义

    今天 我遇到了一些类似这样的代码 namespace Foo public enum Game High Low public enum Switch On Off public class Bar Blah 我无法弄清楚这与在类中声明枚举
  • 如何释放切片分配的内存? [复制]

    这个问题在这里已经有答案了 package main import fmt time func main storage string for i 0 i lt 50000000 i storage append storage strin
  • 在 Eclipse 中复制并粘贴会在每个粘贴行的末尾添加窗口换行符

    我在 Mac OS X 10 7 上使用 Eclipse 版本 Indigo Service Release 2 以及 PHP 开发工具和 Aptana Studio 3 插件 在 首选项 gt 常规 gt 工作区 中 我选择了 文本文件编
  • GTK 中的延迟加载列表视图#

    我希望通过 GTK 中的列表视图显示大型数据集 而性能是这里的一个问题 我目前正在使用由 ListStore 支持的 TreeView 但将所有数据添加到 ListStore 需要很长时间 GTK 中是否有某种支持延迟加载数据的列表视图小部