2017-12-10 4 views
0

私はたくさんのイメージを持つフォルダを持っています。ファイル名を文字列のベクトルにロードして、イメージをGTK :: Imageビデオのようなコンポーネントで、毎秒25フレーム(画像)です。しかし、私はコンポーネントを再描画しないアプリを実行した後。gladeとgtkmmを使ってGtk :: Imageコンポーネントを再ペイントする方法C++

私はqueue_draw()を呼び出しますが、何も変更されません。私はそれをどうやって?

EDIT:

のような主な機能は次のとおりです。

static void on_image_draw(){ 
    string path = video.getDirectory(); 
    string aux = path + "/"; 
    cout << "reproduzindo: " << aux << endl; 
    vector<string> vetor = video.get_imageVector(); 
    cout << "vetor" << endl; 
    for(auto frame: video.get_imageVector()){ 
     aux += frame; 
     cout << "frame: " << aux << endl; 

     image->clear(); 
     image->set(aux); 
     Glib::RefPtr<Gdk::Pixbuf> pix = image->get_pixbuf(); 
     pix = pix->scale_simple(WIDTH, HEIGHT, Gdk::INTERP_BILINEAR); 
     image->set(pix); 

     image->queue_draw(); 
     aux = path+"/"; 
     sleep(1); 
    } 
} 
+0

コードを追加してください。 – anhoppe

+0

ok、コードが追加されました。 –

答えて

0

あなたが描くことになっていない

Glib::RefPtr<Gtk::Application> app = Gtk::Application::create("org.gtkmm.example"); 

refBuilder = Gtk::Builder::create(); 
try{ 
    refBuilder->add_from_file("main_window2.glade"); 
} 
catch(const Glib::FileError& ex){ 
    std::cerr << "FileError: " << ex.what() << std::endl; 
    return 1; 
} 
catch(const Glib::MarkupError& ex){ 
    std::cerr << "MarkupError: " << ex.what() << std::endl; 
    return 1; 
} 
catch(const Gtk::BuilderError& ex){ 
    std::cerr << "BuilderError: " << ex.what() << std::endl; 
    return 1; 
} 

refBuilder->get_widget("main_window", main_window); 
cout << "window: " << main_window << endl; 

if(main_window) 
{ 

    Gtk::ImageMenuItem* newButton = nullptr; 
    Gtk::ImageMenuItem* openButton = nullptr; 
    Gtk::ImageMenuItem* saveButton = nullptr; 
    Gtk::Button* playButton = nullptr; 
    refBuilder->get_widget("new_button", newButton); 
    refBuilder->get_widget("open_button", openButton); 
    refBuilder->get_widget("save_button", saveButton); 
    refBuilder->get_widget("play_button", playButton); 
    refBuilder->get_widget("image_container", container); 
    refBuilder->get_widget("image_component", image_component); 


    if(playButton) 
     playButton->signal_clicked().connect(sigc::ptr_fun(on_image_draw)); 
    if(newButton) 
     newButton->signal_activate().connect(sigc::ptr_fun(on_new_button_activate)); 
    if(openButton) 
     openButton->signal_activate().connect(sigc::ptr_fun(on_open_button_activate)); 
    if(saveButton) 
     saveButton->signal_activate().connect(sigc::ptr_fun(on_save_button_activate)); 

    cout << "running main window" << endl; 
    app->run(*main_window); 
} 

delete main_window; 

とのplayButtonでクリックしたときに、描画コードが呼び出され、すべてのフレームはdrawシグナルハンドラにあります。基本的に画像を設定してからqueue_drawに電話する必要があります。あなたはこの権利をしていますが、GTK +にその作業の一部をさせる必要があります。ちょうどループすることはできません:queue_drawを呼び出すと、画像を描画するためにGTK +が処理する必要のあるメインループにdrawイベントが挿入されます。

あなたはシングルスレッドなので、CPUはシャベルのようなものです。あなたがコールバックしているとき、あなたはシャベルを手に入れて仕事をします。 GTK +にシャベルを返さないと、GTK +が送信したイベントを処理することは期待できません。

ここでは、このようなものを整理する方法を説明します。 25fpsが必要な場合、このアプローチは最適ではないので、おそらくgstreamerのようなビデオライブラリを見てください。

再生を押すと、タイマーやアイドルハンドラのようなイベントソースがトリガーされます。それはあなたが何か言いたいことがあるからです:私は新しいイメージを演出する必要があります。 GLibの中でg_timeout_addまたはg_idle_addを見てください(私はC APIの名前だけを知っています、gtkmmに相当するものを見つける)。

次に、タイムアウトまたはアイドルイベントに関連付けられたコールバックで、イメージを設定します(単一のループ、ループなし)。 queue_drawを呼び出すかどうかは不明です。 GtkDrawingAreaで手描きしていたのですが、それはGtkImageなので、新しい画像を設定すると暗黙のうちに画像が変更され、再描画されるはずです。

+0

それは働いた!ありがとう –

関連する問題