私は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はそれらをすべて再描画します。
誰かが私を助けることができますか?
おかげで、
これで解決できるかどうかはわかりませんが、大きな間違いが2つあります。まず、 'cairo_reference()'と 'cairo_destroy()'を呼び出さないでください。あなたは 'draw'コールバックから得た' cairo_t'を所有していません。次に、 'cairo_fill()'は現在のパスをクリアするので、 'cairo_stroke()'は何も描画しません。代わりに 'ciaro_fill_preserve()'を使用してください。今日は後で詳しく見ていきます。 – andlabs
助けてくれてありがとう、私はあなたが言ったことを修正しましたが、これは私の問題を解決しませんでした。私のコールバック関数は依然として何度も呼び出され、受け取った各コマンドを1つずつ呼び出すことが増えています。 –
ああ、そうだ。変更ごとに 'update_status_led()'を呼び出しています。 'g_signal_connect()'は既存の接続を新しいものに置き換えません。むしろ、既存の接続のリストに新しい接続を追加します。したがって、前に接続したすべてのシグナルハンドラはまだ存在します。コードを変更して 'g_signal_connect()'を1回だけ呼び出す必要があります。おそらく、現在の状態をグローバル変数または最後の 'gpointer'パラメータを介してシグナル関数に渡した共有変数に格納し、' gtk_widget_queue_draw() 'を使用して再描画をスケジュールします。 – andlabs