【问题标题】:Glib signals - How to check if a handler of an instance is already blocked?Glib 信号 - 如何检查实例的处理程序是否已被阻止?
【发布时间】:2013-01-21 00:15:46
【问题描述】:

在实例的处理程序被g_signal_handler_block 阻塞后,是否可以检查处理程序是否仍然被阻塞或同时被 g_signal_handler_unblock 解除阻塞,除了将状态存储在布尔变量中,例如?

我希望这样的事情是可能的

g_signal_handler_block (selection, handler_id_row_selected);
if (g_signal_handler_is_blocked (selection, handler_id_row_selected))
  g_print ("is still blocked");

但是"g_signal_handler_is_blocked" 函数不存在。 g_signal_handler_is_connected 不是正确使用的函数,因为信号处理程序保持连接状态,因此函数返回 TRUE。

我尝试过g_signal_handler_find (),因为G_SIGNAL_MATCH_UNBLOCKED 作为匹配类型之一,但它还没有奏效。即使我已经重写了我的代码,我仍然想知道它是否可能,因为我经常使用阻塞/解除阻塞。

【问题讨论】:

  • 也许您可以编写该函数并在 bugzilla.gnome.org 上的错误报告中提交补丁?看看git.gnome.org/browse/glib/tree/gobject/gsignal.c,实现起来很容易......
  • 虽然我的想法还没有达到那么远,但没有什么可失去的......我会看看 gsignal.c,谢谢你提出这个想法。跨度>

标签: c gtk glib gobject


【解决方案1】:

g_signal_handler_find 这里按预期工作。这是我的测试用例:

#include <gtk/gtk.h>

gboolean
g_signal_handlers_is_blocked_by_func(gpointer instance, GFunc func, gpointer data)
{
    return g_signal_handler_find(instance,
                                 G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA | G_SIGNAL_MATCH_UNBLOCKED,
                                 0, 0, NULL, func, data) == 0;
}

static void
handler(void)
{
    g_print("handler called\n");
}

static void
switch_blocking(GtkWidget *button)
{
    GFunc func = (GFunc) handler;

    if (g_signal_handlers_is_blocked_by_func(button, func, NULL)) {
        g_signal_handlers_unblock_by_func(button, func, NULL);
        g_print("handler unblocked\n");
    } else {
        g_signal_handlers_block_by_func(button, func, NULL);
        g_print("handler blocked\n");
    }
}

int
main(int argc, char **argv)
{
    GtkWidget *window;
    GtkWidget *button;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    button = gtk_button_new_with_label("Click me");

    g_signal_connect_after(button, "clicked", G_CALLBACK(switch_blocking), NULL);
    g_signal_connect(button, "clicked", G_CALLBACK(handler), NULL);

    gtk_container_add(GTK_CONTAINER(window), button);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

【讨论】:

  • 感谢您的示例,我设法将您的示例改编为我的代码,如果 (g_signal_handler_find (selection,G_SIGNAL_MATCH_UNBLOCKED, 0, 0, NULL, NULL, NULL) == 0) 就足够了。如果有一个简单的函数来处理这个问题仍然会很好!
  • 这就是上述g_signal_handlers_is_blocked_by_func() 包装器的用途。此外,您对 g_signal_handler_find 的使用是错误的(或者,更好的是,它没有按照您的要求执行操作):它解除了绑定到选择的 每个 处理程序的阻塞。
  • 也许我说得不够清楚,简单的 if 语句对于我的特殊情况已经足够好了,因为无论如何我只有一个处理程序绑定到选择。这并不是要被理解为比您的解决方案更通用、更简单的解决方案。
  • 代码 sn-p 是一个测试用例,唯一相关的部分是第 7-10 行。我想说的是g_signal_handler_find(selection, G_SIGNAL_MATCH_UNBLOCKED, 0, 0, NULL, NULL, NULL) 不会按照您的问题要求过滤handler_id_row_selected
猜你喜欢
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 2015-09-28
相关资源
最近更新 更多