Fl_Button 回调没有被调用
Fl_Button callback does not get called
我正在用 FLTK 编写一些自定义小部件,一个是用于触摸屏的单个数字微调器,它是一个值,上面有一个箭头,下面有一个箭头。
class Spinner: public Fl_Group
{
private:
::std::unique_ptr<Fl_Button> button_up_;
::std::unique_ptr<Fl_Button> button_down_;
::std::unique_ptr<Fl_Output> value_;
public:
static unsigned int const WIDTH = 36;
static unsigned int const HEIGHT = 100;
...
};
Spinner::Spinner(int x, int y, size_t val)
:Fl_Group(x, y, WIDTH, HEIGHT)
,button_up_(new Fl_Button(x + 2, y + 1, 32, 17))
,button_down_(new Fl_Button(x + 2, y + 82, 32, 17))
,value_(new Fl_Output(x + 2, y + 18, 32, 64))
{
char v[] = {'0', 0};
if (val > 9) val = 9;
v[0] = val + '0';
button_up_->callback(reinterpret_cast<Fl_Callback*>(&Spinner::upcbk), this);
button_down_->callback(reinterpret_cast<Fl_Callback*>(&Spinner::downcbk), this);
button_up_->image(up_arrow);
button_down_->image(down_arrow);
button_up_->color(FL_BLACK);
button_down_->color(FL_BLACK);
button_up_->box(FL_FLAT_BOX);
button_down_->box(FL_FLAT_BOX);
value_->box(FL_BORDER_BOX);
value_->color(FL_BLACK);
value_->labelcolor(FL_RED);
value_->selection_color (FL_RED);
value_->textsize(46);
value_->textcolor(FL_RED);
value_->value(v);
value_->redraw();
end();
}
void Spinner::upcbk(Fl_Widget*, Spinner* spnr)
{
cout << "Spinner::upcbk()" << endl;
spnr->increment();
}
void Spinner::downcbk(Fl_Widget*, Spinner* spnr)
{
cout << "Spinner::downcbk()" << endl;
spnr->decrement();
}
当我在 window 中实例化一个 Spinner 对象时,它工作正常,并且在单击相应的箭头时调用每个回调。
另一个自定义小部件是 Spinner 聚合:
class UintSpinner: public Fl_Group
{
private:
uint16_t value_;
uint16_t const max_;
uint16_t const min_;
uint16_t const order_;
char fmt_[6];
::std::vector< ::std::unique_ptr <Spinner> > spinners_;
...
};
UintSpinner::UintSpinner(int x, int y, uint16_t minval, uint16_t maxval
,uint16_t val)
:Fl_Group(x, y, Spinner::WIDTH * static_cast<uint16_t>(log10(max_)) + 1, Spinner::HEIGHT)
,value_(val < minval ? minval : (val > maxval ? maxval : val))
,max_(maxval)
,min_(minval)
,order_(static_cast<uint16_t>(log10(max_)) + 1)
{
strncpy(fmt_, "%00hu", 6);
fmt_[2] = static_cast<char>(order_) + '0';
char buffer[6];
snprintf(buffer, 6, fmt_, val);
for (ssize_t i = order_ - 1; i >= 0; i--) {
spinners_.emplace_back(new Spinner(x + i * Spinner::WIDTH, y, buffer[i] - '0'));
spinners_.back()->callback(&UintSpinner::spinner_cb, this);
}
}
void UintSpinner::spinner_cb(Fl_Widget* cb, void* p)
{
cout << "UintSpinner::spinner_cb()" << endl;
reinterpret_cast<UintSpinner*>(p)->spinnercb();
}
在这种情况下,如果我实例化一个最大值为 244 的 UintSpinner class 对象,它会正确呈现三个单独的微调器,但当我点击一个时,Spinner::upcbk 和 Spinner::downcbk 都不会被调用的箭头。
我尝试在 Spinner class 中为 Fl_Button 和 Fl_Output 使用堆栈变量,并且行为是相同的。我还尝试创建一个 Spinners 向量而不是一个指针向量,但它无法编译,因为 Fl_Group 似乎不可移动。
我是不是做错了什么?为什么在 Spinner class 中使用完全相同的代码,当直接使用该实例而不是在另一个自定义小部件中使用该实例时,它们的内部成员回调有效?
此致,感谢您的帮助。
好的,我找到了解决方案。
在 UintSpinner 构造函数中,当调用基础 Fl_Group 构造函数时,我传递了一个具有未定义值的宽度参数(复制粘贴错误)。根据 Erco's FLTK Cheat Page -> Fl_Group Event vs. Draw Clipping,当 Fl_Group 的子项扩展到其边界框之外时,默认情况下不会裁剪渲染,但会裁剪其鼠标事件。因此将构造函数更改为:
UintSpinner::UintSpinner(int x, int y, uint16_t minval, uint16_t maxval
,uint16_t val)
:Fl_Group(x, y, Spinner::WIDTH * static_cast<uint16_t>(log10(maxval) + 1), Spinner::HEIGHT)
,value_(val < minval ? minval : (val > maxval ? maxval : val))
,max_(maxval)
,min_(minval)
,order_(static_cast<uint16_t>(log10(max_)) + 1)
{
...
解决问题。
我正在用 FLTK 编写一些自定义小部件,一个是用于触摸屏的单个数字微调器,它是一个值,上面有一个箭头,下面有一个箭头。
class Spinner: public Fl_Group
{
private:
::std::unique_ptr<Fl_Button> button_up_;
::std::unique_ptr<Fl_Button> button_down_;
::std::unique_ptr<Fl_Output> value_;
public:
static unsigned int const WIDTH = 36;
static unsigned int const HEIGHT = 100;
...
};
Spinner::Spinner(int x, int y, size_t val)
:Fl_Group(x, y, WIDTH, HEIGHT)
,button_up_(new Fl_Button(x + 2, y + 1, 32, 17))
,button_down_(new Fl_Button(x + 2, y + 82, 32, 17))
,value_(new Fl_Output(x + 2, y + 18, 32, 64))
{
char v[] = {'0', 0};
if (val > 9) val = 9;
v[0] = val + '0';
button_up_->callback(reinterpret_cast<Fl_Callback*>(&Spinner::upcbk), this);
button_down_->callback(reinterpret_cast<Fl_Callback*>(&Spinner::downcbk), this);
button_up_->image(up_arrow);
button_down_->image(down_arrow);
button_up_->color(FL_BLACK);
button_down_->color(FL_BLACK);
button_up_->box(FL_FLAT_BOX);
button_down_->box(FL_FLAT_BOX);
value_->box(FL_BORDER_BOX);
value_->color(FL_BLACK);
value_->labelcolor(FL_RED);
value_->selection_color (FL_RED);
value_->textsize(46);
value_->textcolor(FL_RED);
value_->value(v);
value_->redraw();
end();
}
void Spinner::upcbk(Fl_Widget*, Spinner* spnr)
{
cout << "Spinner::upcbk()" << endl;
spnr->increment();
}
void Spinner::downcbk(Fl_Widget*, Spinner* spnr)
{
cout << "Spinner::downcbk()" << endl;
spnr->decrement();
}
当我在 window 中实例化一个 Spinner 对象时,它工作正常,并且在单击相应的箭头时调用每个回调。
另一个自定义小部件是 Spinner 聚合:
class UintSpinner: public Fl_Group
{
private:
uint16_t value_;
uint16_t const max_;
uint16_t const min_;
uint16_t const order_;
char fmt_[6];
::std::vector< ::std::unique_ptr <Spinner> > spinners_;
...
};
UintSpinner::UintSpinner(int x, int y, uint16_t minval, uint16_t maxval
,uint16_t val)
:Fl_Group(x, y, Spinner::WIDTH * static_cast<uint16_t>(log10(max_)) + 1, Spinner::HEIGHT)
,value_(val < minval ? minval : (val > maxval ? maxval : val))
,max_(maxval)
,min_(minval)
,order_(static_cast<uint16_t>(log10(max_)) + 1)
{
strncpy(fmt_, "%00hu", 6);
fmt_[2] = static_cast<char>(order_) + '0';
char buffer[6];
snprintf(buffer, 6, fmt_, val);
for (ssize_t i = order_ - 1; i >= 0; i--) {
spinners_.emplace_back(new Spinner(x + i * Spinner::WIDTH, y, buffer[i] - '0'));
spinners_.back()->callback(&UintSpinner::spinner_cb, this);
}
}
void UintSpinner::spinner_cb(Fl_Widget* cb, void* p)
{
cout << "UintSpinner::spinner_cb()" << endl;
reinterpret_cast<UintSpinner*>(p)->spinnercb();
}
在这种情况下,如果我实例化一个最大值为 244 的 UintSpinner class 对象,它会正确呈现三个单独的微调器,但当我点击一个时,Spinner::upcbk 和 Spinner::downcbk 都不会被调用的箭头。
我尝试在 Spinner class 中为 Fl_Button 和 Fl_Output 使用堆栈变量,并且行为是相同的。我还尝试创建一个 Spinners 向量而不是一个指针向量,但它无法编译,因为 Fl_Group 似乎不可移动。
我是不是做错了什么?为什么在 Spinner class 中使用完全相同的代码,当直接使用该实例而不是在另一个自定义小部件中使用该实例时,它们的内部成员回调有效?
此致,感谢您的帮助。
好的,我找到了解决方案。
在 UintSpinner 构造函数中,当调用基础 Fl_Group 构造函数时,我传递了一个具有未定义值的宽度参数(复制粘贴错误)。根据 Erco's FLTK Cheat Page -> Fl_Group Event vs. Draw Clipping,当 Fl_Group 的子项扩展到其边界框之外时,默认情况下不会裁剪渲染,但会裁剪其鼠标事件。因此将构造函数更改为:
UintSpinner::UintSpinner(int x, int y, uint16_t minval, uint16_t maxval
,uint16_t val)
:Fl_Group(x, y, Spinner::WIDTH * static_cast<uint16_t>(log10(maxval) + 1), Spinner::HEIGHT)
,value_(val < minval ? minval : (val > maxval ? maxval : val))
,max_(maxval)
,min_(minval)
,order_(static_cast<uint16_t>(log10(max_)) + 1)
{
...
解决问题。