2016-09-11 15 views
0

gtkのラジオボタンまたはgtkトグルボタンの "up/down"状態を切り替えるgtkのビルトインハンドラへの「クリック」信号のブロックをブロックすることはできますか?GTK +はgtk_radio_buttonまたはgtk_toggle_buttonのデフォルトハンドラをオーバーライドします

背景:

私はネットワーク接続を介してオンとオフ、ハードウェアのGPIOピンをオンにする必要があります(Linuxの& OS Xのために、Cで)GTKアプリケーションに取り組んでいます。メッセージを送信することによって、ピンがオンまたはオフになります(つまり、イベントドリブンです)。ハードウェアは、ハードウェアピンの実際の状態を示すメッセージを定期的に返します。ピンの真の状態が、 (ユーザーの選択状態とは異なる理由がいくつかありますが、私はここには入りません)。私は現在、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); 
} 

コードは動作しますが、2つの問題がある:ラジオボタンの状態が変更した場合、それは2つのメッセージを送信し 1.。 2.ボタンは「クリック」した直後に状態を変更しますが、ハードウェアのピンの状態が異なる場合は再び元の状態に戻ります。

リモートの状態を反映するために通常のgtkボタンや他のタイプのウィジェットでこれを行うことができましたが、私は本当にオン/オフボタンを押して "美しい/美しい"人間工学的理由。

gtkはボタンの状態を内部的に更新するのを止める方法があるので、gtk_toggle_button_set_active()で更新するだけですか?

私の知らないことを許してください、私はGTKにはかなり新しく、おそらくこれには本当に明白な解決策がありますが、私は時間を費やしてグーグルで別のものを試してみると、カスタムウィジェットを書く。

+0

あなたのラジオボタンは状態を示すためにのみ表示されていますが、ユーザーはそれらを変更できませんか?もしそうなら、間違ったツールを使って仕事をしているかもしれません。 GtkDrawingAreaを使って状態を描画し、 'gtk_widget_queue_draw()'を使って調べてみましょう。 – andlabs

+0

こんにちはandlabs、彼らは両方を行う必要はありません:状態を変更&表示する、それはちょうど2つが「デカップリング」する必要があることです。 – Halzephron

答えて

0

私はラジオボタンを使用してトラブルを抱えていましたが、ラジオボタンとして定義するコールバックを使用して、トグルボタンを2つ使用する方が簡単です(私のボタンはMANUAL状態とAUTOmatic状態の間で切り替わります)。 それは少し異なる可能性があるので、私は、PythonでGTKを使用しています(自己。ハンドラである)が、私は考え方が同じ

#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 

私はこれがダブル送信の原因だと思います。ラジオボタングループの1つのボタンをクリックすると、もう一方をクリック解除します。 (私がラジオボタンをあきらめる前に覚えているように、それは間違っている可能性があります)

「内部的に更新している」ことはわかりません。私は、ボタンの変更状態の場合のみ

  1. を知っているように、あなたはSET_ACTIVE()命令
を使用するいくつかの方法で、「クリック」または「トグル」コールバック
  • を実行し、その上に
  • をクリックしてください

    最初の提案は、残りのコードに不要な "トグル"コールバックがあるかどうかを調べることです。私はset_active命令がクリックとしてカウントするとは思わない(しかし、それはトグルとしてカウントすると思う)

    "glitchy"という問題は、すべてのコードを見ることなく解決策を試すのははっきりしない。ごめんなさい。

  • +0

    私は何か似たようなことを考えていました(2つのトグルボタン)。しかし、それでも問題は解決しません。トグルボタンをクリックすると、ハンドラが呼び出されます。しかし、GTK内の内部ハンドラも呼び出すため、ボタンがすぐに上または下に移動します。ユーザーの入力を確認するメッセージをハードウェアから受け取るまでは、ボタンを視覚的に「トグル」する必要はありません。だから私がやりたいことは、トグル/ラジオボタンのビルトインハンドラに伝播した "クリックされた"信号を止めることですが、自分のコールバックを介してシグナルを受け取ります。 – Halzephron

    +0

    「視覚」問題のみを一時的に解決するには、ボタンにCSSを適用することを検討してください。たとえば、アクティブなときは緑色に、非アクティブのときは赤色になります。 Cssはボタンの "状態"を変更しません。独自のコールバックでのみ変更を行います。 [このリンク](https://thegnomejournal.wordpress.com/2011/03/15/styling-gtk-with-css/)を見てください。 – marcoresk

    関連する問題