我在使用GTK3的应用程序中存在一些效率问题,希望您能提供一些帮助。
我有一个在gtk_tree_view中显示的gtk_list_store。 树视图允许选择多行。 我已将回调函数连接到"已更改" tree_selection的事件。 只要用户选择或取消选择任何行,就会调用此回调。 然后进行一些计算,并相应地更新其他gtk小部件的一些图像和内容。 到目前为止这很好。
每当新条目追加到列表存储区(并设置了一些标志)时,我也想将选择设置为树视图的最后一行。
到目前为止我找到的解决方案是取消选择所有行,选择新行并向下滚动视图到最后一个条目:
// 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);
虽然这基本上可以正常工作,但我现在得到两个"改变了#34; gtk_tree_view_selection的事件。
当我在on_selection_changed回调中进行计算并触发重绘某些图形时,我想避免两次完成这项工作。
当然,我可以引入一些全局标志来"忽略取消全部"在回调函数中检查。但这很难看。
是否有某种方法可以在一次调用中更改选择,仅在完成更改后触发一个最终事件? 在完成多个操作时可能会锁定一些事件,并在再次解锁时触发事件?
答案 0 :(得分:1)
每当你connect a callback信号时,你都会获得一个处理程序ID(gulong
)。然后,您可以使用g_signal_handler_block
和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
基本上通过查找已更改信号的处理程序列表中的函数来执行相同的操作。