2017-05-04 15 views
0

動的スライダをGUIウィンドウに追加し、各スライダの変更方法に応じて値をstd::vector<float>に更新しようとしています。 GUIライブラリはコールバックを使用するので、1つのスライダーで成功することができます(または&スライダーのコードを20回貼り付けても解決できません)。しかし、スライダーの作成を関数に分解する際に問題があります。ベクトル内のどの要素を更新するべきかを各スライダに伝える方法の可変寿命。コールバックの値でstd :: vectorを更新する動的なGUIスライダ

nanogui(またはnanoguiを使用するlibigl)を使用していますが、問題は実際にはかなり一般的で、他のGUIフレームワークや状況にも当てはまるはずです。ここで

は1つのスライダーを追加する方法のコードのショートバージョンだと、それは(私は手動で「0」を入れていた注意してください)my_values[0]を更新:

int main(int argc, char *argv[]) 
{ 
    igl::viewer::Viewer viewer; 
    std::vector<float> my_values(50); 
    viewer.callback_init = [&](igl::viewer::Viewer& viewer) 
    { 
    nanogui::Slider* slider = new nanogui::Slider(viewer.ngui->window()); 

    slider->setCallback([&](float value) { 
     my_values[0] = value; // this slider sets the value at element '0' 
     }); 

    viewer.ngui->addWidget("0", slider); 

    viewer.screen->performLayout(); 
    return false; 
    }; 

    viewer.launch(); 
} 

viewer.callback_initに、前に述べたように、私は」これらのスライダーを50個追加したいのですが、明らかに私は&スライダーとそのコールバックコードを50回貼り付けたくありません。しかし、どういうわけかmy_values[i]を渡す必要があります。つまり、各スライダがベクトルのどの要素を更新するかが渡されます。 機能/コールバックが実際に呼び出された時点で、変数value_idが定義されていないので、私は、動作しません。このような何かを試してみました:

int main(int argc, char *argv[]) 
{ 
    igl::viewer::Viewer viewer; 
    std::vector<float> my_values(50); 

    auto add_slider = [&](igl::viewer::Viewer& viewer, std::vector<float>& my_values, int value_id, std::string value_name) 
    { 
    nanogui::Slider* slider = new nanogui::Slider(viewer.ngui->window()); 

    slider->setCallback([&](float value) { 
     my_values[value_id] = value; // offending line, 'value_id' is not initialized 
     // also I'm using 'value_name' to give the slider a name - code omitted 
     }); 
    return slider; 
    }; 

    viewer.callback_init = [&](igl::viewer::Viewer& viewer) { 

    // Now add all 50 sliders (in a for-loop in real code obviously): 
    viewer.ngui->addWidget("0", add_slider(viewer, 0, "0")); 
    viewer.ngui->addWidget("1", add_slider(viewer, 1, "1")); 
    // etc. 

    viewer.screen->performLayout(); 
    return false; 
    }; 

    viewer.launch(); 
} 

私はvalue_id(定数)を作り、いろいろなことを試してみました参照、さらにstd::shared_ptr<int>(私は恐ろしいことを知っています)でも、value_idは常にmy_values[value_id] = value;という行で初期化されません。

どうすればこの問題を解決できますか?私の推測では、GUI /コールバックプログラミングのよく知られているパターン/ソリューションでなければならないと思っています。私はそれをまだ理解していません。

答えて

1

std::vector<float>にスライダーの値を格納する代わりに、map<string, float>またはmap<Slider*, float>を使用してください。したがって、コールバックが呼び出されるたびに、(スライダのアドレスまたは名前によって)更新する変数を知ることになります。

map<Slider*, float> my_values; 
slider->setCallback([&](float value) { 
     my_values[slider] = value; 
     }); 
+0

データ構造は、 'のstd ::ベクトル my_values'は、実際に戻り、'のstd ::ベクトル 'を取る機能を持っている別のライブラリから来ています。可能であれば、私はそれをそのままにしておきたい。そうでなければ 'map 'から 'std :: vector 'に変える必要があるだろうか? (コールバックはこのライブラリ関数を呼び出します)。 therreは別の方法ですか? – Ela782

+0

@ Ela782 Sliderインスタンスをそれらの浮動小数点値にマップする方法が必要です。 'ベクトル'を変更できない場合は、それを保持し、新しい 'std :: map 'を追加することができます。スライダからmy_valuesのインデックスへのマップを保持します。 – sithereal

+0

それは素晴らしい作品です、ありがとう! – Ela782

関連する問題