【问题标题】:Is it possible to refresh/update the data in a treeview?是否可以刷新/更新树视图中的数据?
【发布时间】:2017-06-07 05:34:53
【问题描述】:

我是 GUI 开发的新手,我已经用 gtk+ 3 开发了几天的项目,但我被困在了这一点上。

我的应用程序包含两个树视图,行中的数据是从 sql 查询中获得的,通过右键单击一行会出现一个弹出菜单,提供将数据设置为“已知”的选项,更新数据库表。

以前的数据现在应该属于另一个树视图,并且在应用重新启动时也是如此,但我希望实时进行。

是否可以更新/刷新树视图中的数据?

用函数获取模型:

static GtkTreeStore* create_and_fill(char* known)
{
  GtkTreeStore* store;
  GtkTreeIter iter;
  GtkWidget* tree;
  store = gtk_tree_store_new(2,G_TYPE_STRING,G_TYPE_STRING);

  char source_mac[50] = {0};
  char source_ip[50] = {0};
  int num_fields;

  char query[300] = {0};
  sprintf(query, "select mac,ip from hosts where known=%s", known);
  if(mysql_query(conn, query))
  {
    fprintf(stderr,"%s\n", mysql_error(conn));
  }
  res = mysql_store_result(conn);
  num_fields = mysql_num_fields(res);

  while((row = mysql_fetch_row(res)))
  {
    sprintf(source_mac,"%s", row[0]);
    sprintf(source_ip,"%s", row[1]);
    gtk_tree_store_append(store, &iter, NULL);
    gtk_tree_store_set(store, &iter, MAC_ADDRESS, source_mac, IP_ADDRESS, source_ip,-1);
  }
  gtk_tree_store_append(store, &iter, NULL);
  mysql_free_result(res);
  return store;
}

【问题讨论】:

  • 请向我们展示您目前在该主题上所做的努力。到目前为止你尝试了什么。使用哪种模型来存储数据。

标签: c treeview refresh gtk3


【解决方案1】:

我从未使用过gtk_tree_store,而只使用过gtk_list_store。尽管如此,该逻辑也应该适用于gtk_tree_store

根据新 SQL 查询的结果,可能会更改、添加或删除某些条目。

基本上有两种方法可以更新您的视图。

如果可能在表格中添加和删除行,最简单的方法可能是清理整个树并再次填充它。

GtkTreeIter       iter;
gboolean          iter_valid;

iter_valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
while (iter_valid)
{
  // Maybe additional cleanup of related data
  // gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, .... -1);
  iter_valid = gtk_tree_store_remove(store, &iter);
}
// Maybe update filtering and sorting afterwards
gtk_tree_model_filter_refilter(store_filtered);

// Populate again with result of SQL query.

如果您可以确定只有内容发生了变化,那么您可以在存储中进行更改:

GtkTreeIter       iter;
gboolean          iter_valid;

iter_valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
while (iter_valid)
{
  gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, < add fields here >, -1);

  bool           update = FALSE;
  // Check if this entry needs to be updated
  // .... => set update = TRUE;

  if (update)
    gtk_tree_store_set(store, &iter, < field names and values here... > -1);

  iter_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
}
// Optionally update filtering and sorting...

【讨论】:

    【解决方案2】:

    我最终只是做了一个丑陋的补丁。 我创建了一个删除树视图、重建商店并再次打包它们的函数。

    static void refresh()
    {
    gtk_container_remove(GTK_CONTAINER(box), tree_1);
    gtk_container_remove(GTK_CONTAINER(box), tree_2);
    
    tree_1 = create_view(create_and_fill("true")); // Rebuild the stores and views
    tree_2 = create_view(create_and_fill("false"));
    
    gtk_box_pack_start(GTK_BOX(box),tree_1,FALSE,FALSE,0);
    gtk_box_pack_start(GTK_BOX(box),tree_2,FALSE,FALSE,0);
    
    gtk_box_reorder_child(GTK_BOX(box), tree_1, x); // X being the relative position of your treeview
    gtk_box_reorder_child(GTK_BOX(box), tree_2, x);
    gtk_widget_show_all(box);
    }
    

    【讨论】:

      【解决方案3】:

      我刚刚为点对点公告板编写了一些代码,该公告板可以填充新树或将新行附加到已填充的树上。它使用递归函数来获取树中现有的迭代器。捕获迭代器的数组通过引用传递给此函数。索引 0 处的迭代器为 null,顶级帖子的“inReplyTo”字段为 0。

      为了简洁起见,我在这里只显示相关代码。请注意,第一次调用 updateTree 使用 $data 中的行填充裸树,然后第二次调用追加 $more 中的行。

      <?php
      
        $model = new GtkTreeStore(GObject::TYPE_STRING, GObject::TYPE_LONG);
        $tree  = new GtkTreeView($model);
        $renderer1 = new GtkCellRendererText();
        $column1 = new GtkTreeViewColumn('Title', $renderer1, 'text', 0);
        $renderer2 = new GtkCellRendererText();
        $column2 = new GtkTreeViewColumn('ID', $renderer2, 'text', 1);
        $tree->append_column($column1);
        $tree->append_column($column2);
      
        function getTreeIterators($model, &$iters, $iter = null)
        {
          if ($iter === null) {
            $iter = $model->get_iter_first();
          }
          while ($iter !== null) {
            $cols       = $model->get($iter, 1);
            $id         = $cols[0];
            $iters[$id] = $iter;
            if ($model->iter_has_child($iter)) {
              $child = $model->iter_children($iter);
              getTreeIterators($model, $iters, $child);
            }
            $iter = $model->iter_next($iter);
          }
        } // getTreeIterators
      
        function updateTree($treeView, $data)
        {
          $model    = $treeView->get_model();
          $iters    = array();
          $iters[0] = null;
          getTreeIterators($model, $iters);
          foreach($data as $item) {
            $iters[$item->id] = $model->append($iters[$item->inReplyTo], array($item->title, $item->id));
          }
          $tree->expand_all();
        } // updateTree
      
        $data = array(
                  (object) array('id' => 1, 'inReplyTo' => 0, 'title' => 'First post'),
                  (object) array('id' => 2, 'inReplyTo' => 1, 'title' => 'Re: First post'),
                  (object) array('id' => 3, 'inReplyTo' => 0, 'title' => 'Second post'),
                  (object) array('id' => 4, 'inReplyTo' => 2, 'title' => 'Re: Re: First post'),
                  (object) array('id' => 5, 'inReplyTo' => 3, 'title' => 'Re: Second post'),
                  (object) array('id' => 6, 'inReplyTo' => 0, 'title' => 'Third post')
                );
      
      
         $more = array(
                  (object) array('id' => 7, 'inReplyTo' => 0, 'title' => 'Fourth post'),
                  (object) array('id' => 8, 'inReplyTo' => 1, 'title' => 'Re: That first post'),
                  (object) array('id' => 9, 'inReplyTo' => 5, 'title' => 'Re: Re: Second post')
                 );
      
        updateTree($tree, $data);
        updateTree($tree, $more);
      
      ?>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-10
        • 2011-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-13
        相关资源
        最近更新 更多