Change selected row in gtk_tree_selection from C function

徘徊边缘 提交于 2021-02-11 11:44:31

问题


I have some efficiency concerns in my application using GTK3 and hope you can provide some help.

I have a gtk_list_store that is shown within a gtk_tree_view. The tree view allows selecting multiple rows. I have connected a callback function to the "changed" event of the tree_selection. This callback is called whenever the user selects or unselects any row. Then some calculations are done and some images and contents of other gtk widgets are updated accordingly. This is fine so far.

I also want to set the selection to the last line of the tree view whenever a new entry is appended to the list store (and some flag is set).

The solution that I found so far is to unselect all lines, select the new line and scroll down the view to the last entry:

// 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);

While this basically works fine, I now get two "changed" events for the gtk_tree_view_selection.

As I do calculations and trigger redrawing of some graphics within the on_selection_changed callback I would like to avoid doing the work twice.

Of course I could introduce some global flag to "ignore unselect all" that is checked in the callback function. But this is rather ugly.

Is there some way to change selection in one single call that only triggers one final event after complete change is done? Maybe some locking of events while multiple operations are done and the event is fired when unlocked again?


回答1:


Whenever you 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 to avoid triggering that callback:

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);

If you don't want to keep the handler id around you can also use g_signal_handlers_block_by_func that basically does the same thing by looking up the function in the handlers list of the changed signal.



来源:https://stackoverflow.com/questions/40343004/change-selected-row-in-gtk-tree-selection-from-c-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!