Fl_Button回调不会被调用

时间:2017-09-16 12:02:57

标签: c++ fltk

我在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();
}

当我在窗口中实例化一个Spinner对象时,它可以正常运行,并且在单击相应的箭头时会调用每个回调。

另一个自定义小部件是Spinner agregation:

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();
}

在这种情况下如果我是UntSpinner类的对象,其最大值为244,它会正确渲染三个单独的微调器,但是当我按下其中一个箭头时,Spinner :: upcbk和Spinner :: downcbk都不会被调用。

我试图在Spinner类中使用Fl_Button和Fl_Output的堆栈变量,行为是相同的。我也尝试创建一个Spinners向量而不是指针向量,但它不能编译,因为Fl_Group似乎不可移动。

我做错了吗?为什么在Spinner类中使用完全相同的代码,当直接使用该实例而不是在另一个自定义小部件中使用该实例时,它们的内部成员回调是否有效?

致以最诚挚的问候,谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

好的,我找到了解决方案。

在UintSpinner构造函数中,当调用基础Fl_Group构造函数时,我传递一个带有未定义值的宽度参数(复制粘贴错误)。根据{{​​3}},当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)
{
...

解决问题。

相关问题