2017-09-16 82 views
0

我在FLTK中編寫了一些自定義小部件,其中一個是觸摸屏的單個數字微調,它是一個上面和下面一個箭頭的值。Fl_Button回調不會被調用

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

當我實例在窗口中的一個微調對象時,它的工作原理確定,單擊其對應的箭頭時每次回調函數被調用。

的其他自定義窗口小部件是一個微調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(); 
} 

在這種情況下,如果我istantiate UintSpinner類的對象與244它能正確呈現三個單獨紡紗最大值,但既不微調:: upcbk也不微調::當我擊中其中一個箭頭時,downcbk會被調用。

我試着在Spinner類中使用堆棧變量Fl_Button和Fl_Output,行爲是一樣的。我也嘗試創建一個Spinners向量而不是一個指針向量,但它不能編譯,因爲Fl_Group看起來不可移動。

我做錯了什麼?爲什麼在Spinner類中使用完全相同的代碼時,它們的內部成員回調在直接使用該實例時起作用,而不是在另一個自定義小部件中使用該實例時起作用?

此致敬禮和感謝您的幫助。

回答

0

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

在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) 
{ 
... 

解決該問題。

+0

您可以將其標記爲答案 – cup

+0

是的,但我不允許在發佈後24小時之內這樣做。還剩三個小時。謝謝。 – Patxitron