2016-05-09 25 views
0

私はGTK3とCを使ってledをシミュレートするシンプルなインターフェイスを開発しています。コマンドを受け取ったら、コマンドに従って "led"をオンまたはオフにします。私はカイロを使用して私の主導のサークルを描画する領域を描画しています。私はgtk_widget_queue_draw_areaを使って自分のタイムアウト機能で画面を更新しています。しばらくすると、私のアプリケーションでCPU使用率が100%に上昇します。カイロを使った描画エリア

私はコマンドを受信したとき、私は "on_draw_event_leds" コールバック関数ので

​​

下の関数を呼び出すことが

gboolean on_draw_event_leds(GtkWidget *widget, cairo_t *cr, 
    gpointer user_data) 
{ 
    set_status_led(cr, GPOINTER_TO_INT(user_data)); 
    return FALSE; 
} 

と呼ばれるだから、関数を呼び出す

void set_status_led(cairo_t *cr, int status) 
{ 
    printf("update status led: %d\n", countref++); 
    cairo_reference(cr); 
    cairo_set_line_width(cr, 2); 
    cairo_set_source_rgb(cr, 0, 0, 0); 
    cairo_arc(cr, 9, 9, 7, 0, 2 * M_PI); 
    if (status>0) 
    { 
     cairo_set_source_rgb(cr, 1, 0, 0); //red 
    } 
    else 
    { 
     cairo_set_source_rgb(cr, 0, 0, 0); //black 
    } 
    cairo_fill(cr); 
    cairo_stroke(cr); 
    cairo_destroy(cr); 
} 
を "set_status_led"

私は "printf("更新ステータスled:%d \ n "、countref ++);"私の関数が呼び出されて、私のログを見ることができるように

New Connection from 127.0.0.1:34589 
1 Command Received 
update status led: 6 
update status led: 7 
1 Command Received 
update status led: 8 
update status led: 9 
update status led: 10 
1 Command Received 
update status led: 11 
update status led: 12 
update status led: 13 
update status led: 14 
1 Command Received 
update status led: 15 
update status led: 16 
update status led: 17 
update status led: 18 
update status led: 19 
1 Command Received 
update status led: 20 
update status led: 21 
update status led: 22 
update status led: 23 
update status led: 24 
update status led: 25 
1 Command Received 
... 

の下に印刷された回数を知るために、私は一つのコマンドを受信して​​、私のコールバック関数はon_draw_event_leds何回も呼ばれ、常に各受信した1以上のコール を高めています以前のカイロは削除されず、gtk_widget_queue_draw_areaはそれらをすべて再描画します。

誰かが私を助けることができますか?

おかげで、

+1

これで解決できるかどうかはわかりませんが、大きな間違いが2つあります。まず、 'cairo_reference()'と 'cairo_destroy()'を呼び出さないでください。あなたは 'draw'コールバックから得た' cairo_t'を所有していません。次に、 'cairo_fill()'は現在のパスをクリアするので、 'cairo_stroke()'は何も描画しません。代わりに 'ciaro_fill_preserve()'を使用してください。今日は後で詳しく見ていきます。 – andlabs

+0

助けてくれてありがとう、私はあなたが言ったことを修正しましたが、これは私の問題を解決しませんでした。私のコールバック関数は依然として何度も呼び出され、受け取った各コマンドを1つずつ呼び出すことが増えています。 –

+1

ああ、そうだ。変更ごとに 'update_status_led()'を呼び出しています。 'g_signal_connect()'は既存の接続を新しいものに置き換えません。むしろ、既存の接続のリストに新しい接続を追加します。したがって、前に接続したすべてのシグナルハンドラはまだ存在します。コードを変更して 'g_signal_connect()'を1回だけ呼び出す必要があります。おそらく、現在の状態をグローバル変数または最後の 'gpointer'パラメータを介してシグナル関数に渡した共有変数に格納し、' gtk_widget_queue_draw() 'を使用して再描画をスケジュールします。 – andlabs

答えて

0

g_signal_connect()機能だけで「このイベントが発生したとき、この関数を実行する」と言います。実際にウィジェットを再描画させる機能であるgtk_widget_queue_draw()のために混乱させる可能性があります。

やや直感的には、信号接続は多数あります。これは、任意の数の関数が同じ信号に接続できることを意味し、は、その信号が放出されるときにすべて呼び出されますg_signal_connect()を繰り返し呼び出すため、描画関数への複数の接続が得られ、その描画関数は複数回呼び出されます。

だから、g_signal_connect()を代わりに初期化コードに移動してください。通常、信号はどこにでも接続されており、(または同様の機能)はupdate_status_led()にあります。

関連する問題