我刚刚加入这个神奇的社区,以获得一个非常烦人的问题的答案。 我正在尝试用FLTK创建一个五连胜的游戏。目前我只是将其笨拙的版本打造成tic tac toe。 所以我的问题是: 我用许多按钮创建了一块板。对于tic tac toe,该板只有9个按钮。但是对于五个连续的它是15 * 15所以它是225个按钮。当我必须定义所有回调函数时,真正的问题就开始了。那么有没有办法只为它们所有人提供一个回调函数?我可以为按钮分配一个值,以便回调函数知道在调用回调时按下了哪个按钮吗? 非常感谢任何阅读它的人:)
编辑
所以我试图更进一步,将所有指针保存到向量中的按钮。
vector <Fl_Button *> pointerVec;
/////////the button grid for the board ///////
int counter = 0;
int width = 50, height = 50;
int rowmax = 15, colmax = 15;
for (int rr = 0; rr < 3; ++rr) {
for (int cc = 0; cc < 3; ++cc) {
Fl_Button* bgrid = new Fl_Button(cc * width+80, rr * height+80, width - 5, width - 5);
int rowcol = counter;
pointerVec.push_back(bgrid); //save pointers to the buttons
bgrid->callback(_playerMove_cb, (void*) rowcol);
counter++;
}
}
////////
//then I tried to pass the vector to a callback function by reference
getAi->callback(getAI_cb, (void*)&pointerVec);
///////
static void getAI_cb(Fl_Widget *w, void *client) {
vector<Fl_Button*> &v = *reinterpret_cast<vector<Fl_Button*> *>(client);
// i wanted to do this //
v[1]->color(FL_RED);
}
所以,当我这样做时,程序崩溃了。我打印出2个向量的内存地址,它们位于不同的地址。 有什么我做错了吗? 我想这样做的原因是因为我想给计算机播放器移动的按钮上色。
答案 0 :(得分:1)
像这样的东西。您可以将任何内容作为参数传递。只要确保它不是瞬态的,否则当回调到达它时,它可能最终遍布堆栈或堆。
#include <stdlib.h>
#include <stdio.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <sstream>
#include <iostream>
#include <string>
#include <list>
void ButtonCB(Fl_Widget* w, void* client)
{
int rowcol = (int)client;
int row = rowcol >> 8;
int col = rowcol & 255;
std::cout << "row " << row << " col " << col << std::endl;
}
void CloseCB(Fl_Widget* w, void* client)
{
std::cout << "The end" << std::endl;
exit (0);
}
int main(int argc, char ** argv)
{
int width = 60, height = 25;
int rowmax = 5, colmax = 5;
std::list<std::string> tags;
Fl_Window *window = new Fl_Window(colmax * width + 20, rowmax * height + 20);
for (int rr = 0; rr < rowmax; ++rr)
{
for (int cc = 0; cc < colmax; ++cc)
{
std::ostringstream lab;
lab << "R" << rr << "C" << cc;
// Need to keep the strings otherwise we get blank labels
tags.push_back(lab.str());
Fl_Button* b = new Fl_Button(cc * width + 10, rr * height + 10, width - 5, height - 5, tags.back().c_str());
int rowcol = rr << 8 | cc;
b->callback(ButtonCB, (void*) rowcol);
}
}
window->end();
window->callback(CloseCB, 0);
window->show(argc,argv);
return Fl::run();
}