FLTK:按下哪个按钮 - 将数字传递给按钮的回调(lambda)
Posted
技术标签:
【中文标题】FLTK:按下哪个按钮 - 将数字传递给按钮的回调(lambda)【英文标题】:FLTK: which button is pressed - passing a number to a button's callback (lambda) 【发布时间】:2020-02-19 22:00:15 【问题描述】:我在 FLTK 窗口上有 N
按钮。我想知道用户按下了哪个按钮。如何将数字传递给每个按钮的 lambda 回调函数?到目前为止,我试过这个:
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】:当您注册回调时:
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]);
您看到的“随机”数字绝不是随机的。它们代表您的号码所在的内存中的确切位置。将地址显式转换为数值是完全有效的代码,而这正是您所做的。
【讨论】:
【参考方案2】:您也可以使用小部件的坐标来获取按钮的编号,因为您决定了按钮的位置。
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Button.H>
#include <iostream>
#include <vector>
void show(Fl_Widget *w)
std::cout << w->x()/50+1 << std::endl;
int main(int argc, char **argv)
Fl_Window *w_main = new Fl_Window(640, 480);
Fl_Button* bts[5];
for (int i = 0; i < 5; i++)
char *num = new char;
std::strcpy (num, std::to_string(i+1).c_str());
bts[i] = new Fl_Button(50 * i, 0, 50, 50,num);
bts[i]->callback(show);
w_main->show();
return Fl::run();
通过这种方式,您不必向回调传递任何内容。
【讨论】:
以上是关于FLTK:按下哪个按钮 - 将数字传递给按钮的回调(lambda)的主要内容,如果未能解决你的问题,请参考以下文章