Tôi đang học C++ bằng cách sử dụng cuốn sách Programming Principles and Practice Using C++. Chương 16 bao gồm các kỹ thuật sử dụng phần gui của thư viện FLTK thông qua một thư viện giao diện.Thực hiện một lớp thanh tiến trình
Một trong các bài tập trong chương này là tạo hiệu ứng chuyển động của hình ảnh, được điều khiển bằng nút khởi động và dừng được thực hiện trong một lớp học. Đối với thời gian tôi thấy rằng việc sử dụng FLTKs Fl::add_timeout
và Fl::repeat_timeout
là giải pháp tốt hơn là đi vào vòng lặp vô hạn và sử dụng Sleep(), chặn các cuộc gọi lại khác.
tôi đã không thành công trong việc thực hiện một giải pháp làm việc sử dụng Fl::add_timeout
và Fl::repeat_timeout
, nhưng không tìm thấy một ví dụ here sử dụng một thanh tiến trình với một sự khởi đầu và nút dừng:
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Progress.H>
#include <FL/Fl_Button.H>
Fl_Progress* progBar;
void runcount(void*)
{
if (progBar->value() == progBar->maximum())
{
Fl::remove_timeout(runcount);
progBar->value(0);
}
else
{
Fl::repeat_timeout(1, runcount);
progBar->value(progBar->value() + 1);
}
}
void cb_startb(void)
{
Fl::add_timeout(1, runcount);
}
void cb_stopb(void)
{
Fl::remove_timeout(runcount);
}
int main (int argc, char *argv[])
{
Fl_Double_Window window(200,70,"ProgressBar Test");
progBar = new Fl_Progress(5, 10, window.w()-10, 20);
progBar->box(FL_SHADOW_BOX);
progBar->selection_color((Fl_Color)4);
progBar->minimum(0);
progBar->maximum(10);
Fl_Button* start_button = new Fl_Button(10, 40, 80, 20, "START");
start_button->box(FL_SHADOW_BOX);
start_button->callback((Fl_Callback*)cb_startb,(void*)"start");
Fl_Button* stop_button = new Fl_Button(110, 40, 80, 20, "STOP");
stop_button->box(FL_SHADOW_BOX);
stop_button->callback((Fl_Callback*)cb_stopb,(void*)"stop");
window.end();
window.show(argc, argv);
return Fl::run();
}
Ví dụ này biên dịch và hoạt động tốt.
Sau đó tôi đã cố gắng đưa ví dụ về thanh tiến trình cùng nhau trong một lớp và đây là nơi tôi bị kẹt.
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Progress.H>
#include <FL/Fl_Button.H>
#include <string>
class ProgressBar : public Fl_Double_Window {
public:
ProgressBar(int w, int h, const std::string label)
: Fl_Double_Window{ w,h,label.c_str() }
{
progBar = new Fl_Progress(5, 10, 10, 20);
progBar->box(FL_SHADOW_BOX);
progBar->selection_color((Fl_Color)4);
progBar->minimum(0); // set range: 0-10
progBar->maximum(10);
start_button = new Fl_Button(10, 40, 80, 20, "START");
start_button->box(FL_SHADOW_BOX);
start_button->callback((Fl_Callback*)cb_startb, (void*)"start"); //compile error: 'type-cast':cannot convert
//from 'overloaded-function'..
stop_button = new Fl_Button(110, 40, 80, 20, "STOP");
stop_button->box(FL_SHADOW_BOX);
stop_button->callback(static_cast<Fl_Callback*>(cb_stopb), (void*)"stop");//(Fl_Callback*)cb_stopb
//compile error: 'type-cast':cannot convert from 'overloaded-function'..
}
~ProgressBar()
{
delete progBar;
delete start_button;
delete stop_button;
}
private:
void runcount(void*)
{
if (progBar->value() == progBar->maximum())
// max reached, stop timer and reset pregress bar to 0
{
Fl::remove_timeout(runcount); // non-standard syntax, use & to create a pointer to member
progBar->value(0);
}
else
// timer running, recursive calling this function - increase progress bar by 1.
{
Fl::repeat_timeout(0.1, runcount); ///compile error: non-standard syntax, use & to create a pointer to member
progBar->value(progBar->value() + 1);
}
}
void cb_startb(void)
{
Fl::add_timeout(1, runcount);///compile error: non-standard syntax, use & to create a pointer to member
}
void cb_stopb(void)
{
Fl::remove_timeout(runcount);///compile error: non-standard syntax, use & to create a pointer to member
}
Fl_Button* start_button;
Fl_Button* stop_button;
Fl_Progress* progBar;
};
int main()
{
ProgressBar* progBar = new ProgressBar{200, 700,"Progress bar" };
progBar->end();
progBar->show();
return Fl::run();
delete progBar;
}
Tôi không thể tìm hiểu cách triển khai chức năng gọi lại. Tôi nhận được các lỗi biên dịch như được viết trong các ý kiến.
Nếu tôi đặt chức năng tĩnh runcount()
, lỗi biên dịch trên 4 cuộc gọi đến runcount()
sẽ biến mất, nhưng điều đó không có ý nghĩa với tôi để làm cho hàm này tĩnh. Tôi gặp lỗi mới về cuộc gọi progBar.
Làm cách nào để triển khai lớp học này, để sử dụng chức năng bắt đầu và dừng?
Tôi có thể thiếu một số kiến thức về cách hoạt động của chức năng gọi lại và sử dụng con trỏ, đó là lý do tại sao tôi cố gắng làm việc này.