【问题标题】:Suppress GTK signal when callback is triggered via code通过代码触发回调时抑制 GTK 信号
【发布时间】:2012-11-01 03:59:09
【问题描述】:

要点

handler_block 在具体情况下很有用,但我宁愿在程序的开头调用一些东西来抑制对gtk_entry_set_text 和 gtk_toggle_button_set_active 的所有调用的信号。有什么办法吗?


背景信息

我的程序用于通过具有以下属性的角色创建对话框创建实体:

名称 - 通过 GTKComboBoxes 从预先确定的列表中选择
动画 - 也是一个 GTKComboBox
组 - 对实体进行分类的六个单选按钮之一

可以添加实体 - 从一个空白的添加对话框开始,填写所有字段,然后提交。
实体可以通过“编辑”对话框进行编辑,上面列出的所有字段最初都是用实体的当前属性填充的。编辑是即时的(编辑对话框上没有提交按钮),一旦选择组合按钮或单选按钮中的新值,显示的实体就会出现不同。

我有一个连接到 Type 条目并由“更改”信号触发的回调。每当我在代码中手动设置条目文本以显示正在编辑的实体时,回调似乎都会触发:

gtk_entry_set_text(GTK_ENTRY(name_entry), entity.name); // name is a char*
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (group_button_friendly), TRUE);

是的,g_signal_handler_block 有办法,但需要

1) 获取在您首先连接信号时创建的gulongg_signal_connect(args); 对比 gulong entry_handler_id = g_signal_connect(args);

2) 每次调用都使用阻止/解除阻止的习惯用法。
g_signal_handler_block(args, entry_handler_id);
gtk_entry_set_text(args);
g_signal_handler_unblock(args, entry_handler_id);
或者更糟,
g_signal_handler_block(args, entry_handler_id);
fn_that_calls_gtk_entry_set_text();
g_signal_handler_unblock(args, entry_handler_id);

【问题讨论】:

  • 您能否将表单中的文本与“保存”的信息进行比较并返回?我不知道是否有办法从触发中清除事件。在我正在编写的应用程序中,我只有 on changed 事件或任何写出它的价值的东西,基本上意味着你写了你刚刚写回的东西,但它并没有真正妨碍我(假设你没有做你的回调中有什么特别的东西)。
  • 您可以设置一些标志变量来告诉处理程序什么也不做,而不是像那样阻塞您自己的处理程序。 [据我了解,GTK+ 即使对源代码的更改也会发出信号的原因是稳健性。例如。两个库(或一个库和您自己的代码)可以连接到同一个对象,并且仍然可以看到彼此所做的更改。]
  • 感谢@doublep 的解释。我快疯了,诅咒这个库的创建者,但很高兴知道这个令人沮丧的概念背后是有原因的。我目前正在使用一个名为 _suppress_callback 的 bool,尽管它只解决了问题 (1),并且仍然需要我用两行代码来预订有问题的函数。
  • @senshikaze,我最终按照您的建议将回调值与保存的值进行了比较。谢谢。

标签: c++ callback gtk gtkmm


【解决方案1】:

我认为您正在寻找的是g_signal_handlers_block_matched。如果您将掩码设置为 G_SIGNAL_MATCH_CLOSURE 并在信号中使用闭包,它应该可以解决问题。

您必须在signal_id 中查找正在发出的信号,但您应该只需要这样做一次,因为所有小部件之间的信号 id 都是相同的,这就是为什么需要实例电话也是。

要解除阻止,您想使用g_signal_handlers_unblock_matched

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    相关资源
    最近更新 更多