从 C 函数更改 gtk_tree_selection 中的选定行

Change selected row in gtk_tree_selection from C function

我在使用 GTK3 的应用程序中遇到一些效率问题,希望您能提供一些帮助。

我有一个显示在 gtk_tree_view 中的 gtk_list_store。 树视图允许 selecting 多行。 我已将回调函数连接到 tree_selection 的 "changed" 事件。 每当用户 selects 或 unselects 任何行时都会调用此回调。 然后进行一些计算,并相应地更新其他 gtk 小部件的一些图像和内容。 目前为止一切正常。

我还想将 selection 设置为树视图的最后一行,每当新条目附加到列表存储(并设置了一些标志)时。

目前我找到的解决方案是取消select所有行,select新行并向下滚动视图到最后一个条目:

// Create new entry
gtk_list_store_append(liststore, &iter);
...
// Set data for entry
gtk_list_store_set(liststore, &iter, ......);
...
// Make the new entry the (only) selected row
gtk_tree_selection_unselect_all(packet_tree_view_selection);
gtk_tree_selection_select_iter(packet_tree_view_selection, &filter_iter);
...
// scroll down to the new entry
GtkTreeModel *model = gtk_tree_model_filter_get_model(packet_store.filtered);
GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
gtk_tree_view_scroll_to_cell(packet_tree_view, path, NULL, FALSE, 1.0, 0.0);

虽然这基本上可以正常工作,但我现在为 gtk_tree_view_selection 获得了两个 "changed" 事件。

当我在 on_selection_changed 回调中进行计算并触发某些图形的重绘时,我想避免重复执行该工作。

当然,我可以向 "ignore unselect all" 引入一些在回调函数中检查的全局标志。但这有点难看。

有没有什么方法可以在一次调用中更改 selection,在完成更改后仅触发一个最终事件? 也许在完成多个操作时锁定事件,并在再次解锁时触发事件?

每当您 connect a callback to a signal, you get a handler id (a gulong). You can then use g_signal_handler_block and g_signal_handler_unblock 避免触发该回调时:

gulong changed_id;
changed_id = g_signal_connect(packet_tree_view_selection,
                              "changed",
                              ...);
...
g_signal_handler_block(packet_tree_view_selection, changed_id);
gtk_tree_selection_unselect_all(packet_tree_view_selection);
g_signal_handler_unblock(packet_tree_view_selection, changed_id);
gtk_tree_selection_select_iter(packet_tree_view_selection, &filter_iter);

如果您不想保留处理程序 ID,您也可以使用 g_signal_handlers_block_by_func,它基本上通过在已更改信号的处理程序列表中查找函数来执行相同的操作。