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

창에서 하나의 Spinner 개체를 인스턴스화하면 해당 화살표가 클릭 될 때마다 각 콜백이 호출됩니다. 나는 최대 올바르게 세 개의 개별 스피너를 렌더링 (244)의 값 만도 스피너 :: upcbk도 스피너와 UintSpinner 클래스의 객체를 istantiate 경우

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

이 경우 :

다른 사용자 정의 위젯은 스피너 agregation입니다 :: downcbk가 화살표 중 하나를 칠 때 호출됩니다.

Spinner 클래스 내에서 Fl_Button 및 Fl_Output에 스택 변수를 사용하려고했지만 동작은 동일합니다. 나는 또한 포인터의 벡터 대신 Spinners의 벡터를 만들려고했지만 Fl_Group이 움직이지 않는 것처럼 보이기 때문에 컴파일되지 않는다.

내가 잘못 했나요? Spinner 클래스에서 똑같은 코드를 사용하는 이유는 내부 멤버 콜백이 해당 인스턴스를 직접 사용할 때 작동하고 다른 사용자 정의 위젯 내부에서 인스턴스를 사용할 때 작동하지 않는 이유는 무엇입니까?

귀하의 도움에 감사드립니다.

답변

0

좋아, 해결책을 찾았습니다.

UintSpinner 생성자에서 기본 Fl_Group 생성자를 호출 할 때 정의되지 않은 값 (복사 - 붙여 넣기 오류)이있는 width 매개 변수를 전달합니다. 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 시간이 지나야 허용됩니다. 3 시간 남았습니다. 고맙습니다. – Patxitron