質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.98%

  • C

    3089questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • GTK+

    16questions

    GTK+とはGUIを作るために作られた、とても使いやすく機能に富んだツールキットです。クロスプラットフォームによる互換性と、使いやすいAPIを備えています。

gtkでアニメーション

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 276

Tack

score 4

gtkで写真をコマ送り表示でするプログラムを作成しています。
しかし、ループ文が上手く動作しません。
お力を貸してください。

やりたいことは以下の通りです。
boxに写真を表示し、timeout_addで1秒毎に写真を更新。

写真はOpenCVを使用して、USBカメラから100fpsでキャプチャした画像を同じファイル名で保存し、上書きし続けるようになっています。

以下に私の書いたソースコードを添付します。

include <gtk/gtk.h>

GtkWidget *window;
GtkWidget *vbox;
GtkWidget *image;
GtkWidget *button;

static void cb_button_clicked (GtkWidget *button, gpointer user_data)    /*ボタン押下で終了する関数*/
{
gtk_main_quit ();
}

static gboolean capture_loop(GtkWidget *box)    /*t*/
{
image = gtk_image_new_from_file ("/home/pi/project/cam3/Capture.jpg");        /*ファイルから画像を読み込んでイメージの作成*/
gtk_box_pack_start (GTK_BOX (hbox), image, TRUE, TRUE, 0);                                                        /*イメージをボックスに配置*/
return (TRUE);
}

int
main(int argc, char** argv)
{        
gtk_init (&argc, &argv);                                                                /*GTK初期化*/
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);        /*ウィンドウの作成*/
gtk_widget_set_size_request (window, 500,400);            /*大きさ設定*/

{
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);        /*縦にウィジェットを配置するボックスの作成*/
gtk_container_add (GTK_CONTAINER (window), vbox);        /*ボックスをウィンドウに配置*/

button = gtk_button_new_with_label ("✕");                                                                                                                    /*終了ボタン作成*/
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);                                                                        /*ボタンをboxに配置*/
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (cb_button_clicked), NULL);        /*ボタンに関数リンク*/

g_timeout_add(1000, (GSourceFunc)capture_loop, NULL);                                                                    /*ループ文*/
}

g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);        /*ウィンドウを閉じる際にプログラム終了*/
gtk_widget_show_all (window);                                                                                                        /*ウィンドウの表示*/
gtk_main ();                                                                                                                                                        /*メインループ(ユーザーからの操作待ち)*/

return 0;
}

実行すると、写真は表示されず、終了ボタンのみ表示されます。
どこがおかしいのでしょうか。
ご回答よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

こんにちは。

※ご提示のコード中にUSBカメラでjpegの静止画ファイルを保存している処理が無いので、
それは別のプログラムがやっている、との前提で回答させてもらっています。

gtkを試せる環境にないので想像なのですが、こちらの情報を見ると、

gtk - Image not showing when loaded from file

capture_loop()中のgtk_image_new_from_file() の呼び出しは1回だけが有効で、それ以降
ウィジェットに画像をセットするのは gtk_image_new_from_file()が必要な気もします。

gtk-image-set-from-file

capture_loop() 自体が確実に呼び出され、2回目以降をスキップさせるようにして
最初の1回だけは確実に表示されることを確認してみると良いと思います。(これはOKでしょうか?)

あと、この手のGUIモノで良くあるのは、「表示はGUI用のスレッドで実行しなければならない」
と言うものがあります。g_timeout_add()で登録されたコールバック関数が
別のスレッドで実行される場合、描画処理を行うのは問題があるかもしれません。
(想像なので、外していたらすみません)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/04 14:19

    ご回答ありがとうございます。
    早速ご指摘の通り修正したところ、画像が表示され1秒毎に更新されるようになりました。
    しかし、OpenCVで元の画像ファイルを書き換えている瞬間に、GTKで画像を取りに行ってしまうと、画像が正常に読み込めずチラついてしまいます。
    そこで、画像ファイルを書き換えている瞬間にGTKで画像を取りに行ってしまった時は、再度画像を取りにいき、チラつきを無くしたいのですが、どういった条件処理をしたらよいでしょうか。
    アイデアがあれば提供していただければと思います。

    キャンセル

  • 2017/10/04 17:15

    OpenCVで画像を保存するのが「保存PGM」、GTKの表示用プログラムは
    「表示PGM」と、2つのプログラム(実行ファイル)であることを前提で
    お話を進めます。本来であれば保存PGMと表示PGM間でプロセス間通信で
    同期を取り、「画像ファイル作成〜保存終了」をイベントとして
    表示用プログラムが読み取り開始するような作りにすると思います。
    ですが今回はそれはやり過ぎだと思うので、もう少し簡単にいきます。

    1. 保存PGMで、静止画を撮り、保存するときのファイル名を
    「filenameA」とします。
    2. 表示PGMでは読み出す時のファイル名を「filenameB」とします。
    3. 表示PGMは今まで通り、1000ミリ秒周期でfilenameBを読みに行きます。
    読めなければ何もせず、前の表示のまま終わります。
    読めれば表示して、表示が終わったらfilenameBのファイルを
    deleteします。(大事)

    4. 保存PGMでは、filenameAで開いたファイルを書き終わり、closeしたら、
    filleameBへrenameします。もしここでrenameに失敗したら、
    filenameBはまだ表示PGMで表示処理中です。この場合、放置します。
    5. 保存PGMでは前のfillenameAが存在してもしなくても、新たに静止画を
    撮影してfilenameAに上書き保存します。filenameAの持ち主は常に
    保存PGMなので、影響しません。最後にfilenameBへrenameすることが
    キモになります。rename が正常終了してfilenameBが出現したとき、
    ファイルは表示PGMの、いうなれば所有物になります。
    これで基本的に競合しないはずです。

    上記は一例です。ファイルのrenameやdeleteの挙動はWindouxと
    Linuxで異なるので、思い通りにいかない可能性も少しありますが、
    おおむねこのような排他処理が必要になるかと思います。
    あとは、有名な「ロックファイルによる排他」制御があります。
    それを使ってもできます。「linux ロックファイル 排他」
    などでググってみてください。ものの考え方はWindowsでも使えます。

    キャンセル

  • 2017/10/04 17:22

    一部修正:”3. 表示PGMは今まで通り、1000ミリ秒周期でfilenameBを読みに行きます。”の部分ですが、gtk-image-set-from-file()で読み取ってしまうと表示がブランクになってしまうと思うので、fopen()やopen()等でのファイルの存在確認だけにしてください。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    コンストラクタが処理されません

    実現したいことボタンを押すとHello Worldが10回表示されて終了するソースコードを書きたいです。 発生している問題動かしてボタンを押してみると、"ボタンクリック確認"は表示

  • 解決済

    PyQt4におけるシグナル/スロットについて。無限ループしてしまう。

    毎度のことお世話になっております。 現在、python3.4言語でPyQt4を学んでいます。 本当ならPyQt4の書籍で学びたいのですが、 今現在、日本語によるものがない

  • 解決済

    【RubyGTK3】RubyGTK3を使ったプログラムのexe化について

    前提・実現したいこと Rubyでデスクトップマスコット(現時点では透過pngを画面に表示するだけ)の制作を目指しています。 できあがったプログラムをocraでexe化しようとす

  • 受付中

    actionPerformed

    public void actionPerformed(ActionEvent e) { if(btn[0].isSelected()) {

  • 解決済

    opencv 動画 再生

    #include <stdio.h> #include <cv.h> #include <highgui.h> int main(int argc, char* argv[])

  • 解決済

    [Qt]Qtのイベント操作

    (趣味で)C++でやっています。 C++ではGUIはQtが楽らしいので使ってみました。 以前質問したDLL云々は何とか解決しました。 QtCreator付属のヘルプ (

  • 解決済

    [Qt]Qtのデザイン

    趣味でC++やっています。 馬鹿っぽい質問ですが、Windows上でQtを使う場合でMacのデザインにすることは可能でしょうか。 私はWindows上でしか使ったことがない

  • 解決済

    GtkmmのtextViewのカーソルの位置を移動させたい

    gtkmmを使って、テキストエディタを作ろうとしています。 textViewウィジェットのカーソルの位置をコマンドで移動できるようにしたいのですが、メソッドでカーソル位置を移動

同じタグがついた質問を見る

  • C

    3089questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • GTK+

    16questions

    GTK+とはGUIを作るために作られた、とても使いやすく機能に富んだツールキットです。クロスプラットフォームによる互換性と、使いやすいAPIを備えています。