GTK +覆盖gtk_radio_button或gtk_toggle_button的默认处理程序

时间:2016-09-11 19:04:03

标签: c gtk

是否可以阻止"点击"来自gtk的内置处理程序的信号,该处理程序切换"向上/向下"一对gtk单选按钮或gtk切换按钮的状态?

背景:

我正在开发一个GTK应用程序(在C中,用于linux和OS X),它需要通过网络连接打开和关闭硬件GPIO引脚。通过发送消息来打开或关闭引脚(即它是事件驱动的。)硬件周期性地发回消息,该消息给出了硬件引脚的实际状态,并且引脚的真实状态反映到用户(它可能与用户的选择状态有所不同,原因有很多,我不会进入。)我目前正在使用一对gtk单选按钮打开和关闭引脚,我把它们设置成这样:

void create_control_buttons(control_t *item)
{
    assert(item != NULL);

    // Create grouped Gtk radio buttons.
    item->button0 = gtk_radio_button_new_with_label(NULL, "Off");
    item->button1 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(item->button0), "On");

    // Make the radio buttons look like normal buttons.
    gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(item->button0), FALSE);
    gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(item->button1), FALSE);

    g_signal_connect(G_OBJECT(item->button0), "clicked", G_CALLBACK(on_control_clicked), (gpointer)item);
    g_signal_connect(G_OBJECT(item->button1), "clicked", G_CALLBACK(on_control_clicked), (gpointer)item);

}


void on_control_clicked(GtkWidget *widget, gpointer user_data)
{
    control_t *item = user_data;
    assert(item != NULL);

    if (widget == item->button0) {
        // Send 'off' signal

    } else if (widget == item->button1) {
        // send 'on' signal

    }
}

当从硬件接收到周期性状态消息时,将调用另一个函数。它会像这样更新按钮状态:

if (state == ON) {
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(item->button1), 1);
} else {
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(item->button0), 1);
}

代码有效,但有两个问题: 1.如果单选按钮改变状态,它会发送两条消息。 2.按钮将立即改变状态"点击"但如果硬件引脚状态不同,将会再次改变,从而导致一个相当不正常的问题。外观

我可以使用普通的gtk按钮和其他类型的小部件来反映远程状态,但我真的希望开/关按钮保持按下状态" up"或" down"以美学/人体工程学的原因显示状态。

有没有办法在内部停止gtk更新按钮状态,所以只能用gtk_toggle_button_set_active()来更新?

请原谅我的无知,我对GTK很陌生,这可能是一个非常明显的解决方案,但我花了很多时间谷歌搜索并尝试不同的事情无济于事我真的想避免编写自定义小部件。

1 个答案:

答案 0 :(得分:0)

我使用单选按钮遇到了麻烦,我发现使用几个切换按钮(我的按钮在MANual状态和AUTOmatic状态之间切换)和一个将它们定义为单选按钮的回调更容易。 我正在使用GTK与Python,所以它可能有点不同(自我。是处理程序),但我认为这个想法是相同的

  #Defines the MAN/AUTO button as radio button on CLICKING
  def on_MAN_button_clicked(self, togglebutton, data=None):  
    if self.MAN_button.get_active() == True:
      self.AUTO_button.set_active(False)

  def on_AUTO_button_clicked(self, togglebutton, data=None):  
    if self.AUTO_button.get_active() == True:
      self.MAN_button.set_active(False)

所以也许你可以用条件

改变你的第一个IF结构
#Pseudocode
IF thisbutton.get_active() == 1: send 'on' signal
ELSE IF otherbutton.get_active() == 1: send 'off' signal

我认为这是双重发送的原因:通过单击radiobutton组的一个按钮,您将“取消”另一个按钮。 (我记得在放弃单选按钮之前,这可能是错误的)

我不确定什么是“内部更新”。据我所知,按钮仅在

时改变状态
  1. 你点击它
  2. 以某种方式执行“click”或“toggling”回调
  3. 您使用set_active()指令
  4. 所以我的第一个建议是:搜索其余代码中是否存在不需要的“切换”回调。我不认为set_active指令算作点击(但我认为它算作切换)

    对于我来说,在不看所有代码的情况下尝试解决方案,“毛刺”问题很难说清楚。遗憾。

相关问题