FLTK: какая кнопка нажата - передача номера для обратного вызова кнопки (лямбда) - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть N кнопки в окне FLTK. Я хотел бы знать, какая кнопка была нажата пользователем. Как я могу передать число лямбда-функции обратного вызова каждой кнопки? До сих пор я пробовал это:

int main(int argc, char **argv) {
  Fl_Window *w_main = new Fl_Window(640, 480);

  std::vector<int> nums;
  for (int i = 0; i < 5; i++) {
    nums.push_back(i);

    Fl_Button *btn1 = new Fl_Button(50 * i, 0, 50, 50);
    char const *num = std::to_string(i).c_str();
    btn1->label(num);
    btn1->callback(
        [](Fl_Widget *w, void *data) { std::cout << "Clicked on: " << (int)data << std::endl; },
        &nums[i]);
  }
  w_main->show();
  return Fl::run();
}

К сожалению, я получаю случайные числа на выходе (я предполагаю, что некоторый случайный мусор памяти интерпретируется как целые числа).

Не могли бы вы помочь мне найти решение? Спасибо!

1 Ответ

1 голос
/ 20 февраля 2020

Когда вы регистрируете свой обратный вызов:

btn1->callback(
        ...,
        &nums[i]);

Вы передаете адрес из nums[i] в качестве аргумента обратного вызова (в отличие от самого значения). Таким образом, вам нужно интерпретировать data как указанный адрес и разыменовать его для доступа к базовому номеру.

Это означает:

btn1->callback(
        [](Fl_Widget *w, void *data) { std::cout << "Clicked on: " << *reinterpret_cast<int*>(data) << std::endl; },
        &nums[i]);

«Случайные» числа, которые вы видите, не являются случайными , Они представляют точное местоположение в памяти, где находится ваш номер. Явное преобразование адреса в числовое значение - это совершенно правильный код, и это именно то, что вы сделали.

...