FLTK:在绘制另一个图形时清除图形
FLTK: Clearing a graph when drawing another
我编写了一个简单的 FLTK 程序,当点击“画圆”按钮时画圆,当点击“画线”按钮时画线。我应该只有一张图。但是我在面板中得到了两个图表。我只想要一个显示,另一个消失。以下是代码:
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Box.H>
using namespace std;
int flag = 0;
class Drawing : public Fl_Box {
void draw() {
fl_color(255, 0, 0);
int x, y, x1, y1;
if (flag == 1) {
double radius = 100;
x = (int)(w() / 2);
y = (int)(h() / 2);
fl_circle(x, y, radius);
}
else if (flag == -1) {
x = (int)(w() / 4);
y = (int)(h() / 4);
x1 = (int)(w() *3/ 4);
y1 = (int)(h() *3/ 4);
fl_line(x, y, x1, y1);
}
}
public:
Drawing(int X, int Y, int W, int H) : Fl_Box(X, Y, W, H) {}
};
Drawing* d;
void circle_cb(Fl_Widget*, void*) {
flag = 1;
fl_overlay_clear();
d->redraw();
} // end sumbit_cb
void line_cb(Fl_Widget*, void*) {
flag = -1;
fl_overlay_clear();
d->redraw();
} // end clear_cb
int main(int argc, char** argv) {
Fl_Window* window = new Fl_Window(600, 550); // create a window, originally(400,400)
Drawing dr(0, 0, 600, 600);
d = &dr;
Fl_Button *b, *c;
b = new Fl_Button(150, 80, 100, 25, "&Draw Circle");
b->callback(circle_cb);
c = new Fl_Button(350, 80, 100, 25, "&Draw Line");
c->callback(line_cb);
window->end(); //show the window
window->show(argc, argv);
return Fl::run();
}
我已经使用 fl_overlay_clear() 来清除图表。但是它不起作用。任何帮助将不胜感激。
在你的 handle() 方法 line_cb()
中,circle_cb()
应该调用 window()->make_current()
然后 fl_overlay_rect()
在 FL_DRAG
事件之后,并且应该调用 fl_overlay_clear()
在 FL_RELEASE event
之后。 Refer了解更多详情
您的程序中有几个问题需要解决,但首先像您一样使用 draw() 方法基本上是正确的。但是,使用 fl_overlay_clear();没用的,可以去掉。
我的解决方案:您的小部件没有纯色背景 (boxtype),即您的绘制方法一遍又一遍地在背景上绘制 w/o 清除它。有几种方法可以解决这个问题,但如果您想了解会发生什么,请先尝试这个:在 window->show(argc, argv);
之前添加 window->resizable(window);
,再次 运行 程序并调整 window 的大小.您会注意到之前的绘图消失了,只剩下一张绘图。那是因为当你调整小部件的大小时背景被清除了。
下一步:添加实心框类型:
d = &dr;
d->box(FL_DOWN_BOX);
并在 draw()
方法的开头添加 Fl_Box::draw();
。
如果您这样做,您可能会注意到当您单击其中一个按钮时,您的按钮会消失 - 因为您的按钮 在 您的 Drawing
区域中.我修复的最后一件事是更正按钮的坐标并放大 window(无论如何它太小无法覆盖整个 Drawing
)。这是我的完整结果:
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Box.H>
using namespace std;
int flag = 0;
class Drawing : public Fl_Box {
void draw() {
Fl_Box::draw();
fl_color(255, 0, 0);
int x, y, x1, y1;
if (flag == 1) {
double radius = 100;
x = (int)(w() / 2);
y = (int)(h() / 2);
fl_circle(x, y, radius);
} else if (flag == -1) {
x = (int)(w() / 4);
y = (int)(h() / 4);
x1 = (int)(w() * 3 / 4);
y1 = (int)(h() * 3 / 4);
fl_line(x, y, x1, y1);
}
}
public:
Drawing(int X, int Y, int W, int H)
: Fl_Box(X, Y, W, H) {}
};
Drawing *d;
void circle_cb(Fl_Widget *, void *) {
flag = 1;
// fl_overlay_clear(); // not useful
d->redraw();
} // end sumbit_cb
void line_cb(Fl_Widget *, void *) {
flag = -1;
// fl_overlay_clear(); // not useful
d->redraw();
} // end clear_cb
int main(int argc, char **argv) {
Fl_Window *window = new Fl_Window(600, 660); // create a window, originally(400,400)
Drawing dr(0, 60, 600, 600); // FIXED
d = &dr;
d->box(FL_DOWN_BOX); // ADDED
Fl_Button *b, *c;
b = new Fl_Button(150, 20, 100, 25, "&Draw Circle"); // FIXED
b->callback(circle_cb);
c = new Fl_Button(350, 20, 100, 25, "&Draw Line"); // FIXED
c->callback(line_cb);
window->end(); // show the window
window->resizable(window); // ADDED
window->show(argc, argv);
return Fl::run();
}
我相信这可以满足您的需求。
PS:可以在我们的网站上找到官方 FLTK 支持论坛 https://www.fltk.org/ and the direct link to the user forum (Google Groups) is https://groups.google.com/g/fltkgeneral
只是对 Albrecht 如此完美的补充:FLTK 绘图坐标是相对于 window,而不是相对于小部件的。您可能希望通过小部件的 x()
和 y()
坐标偏移绘图。
我编写了一个简单的 FLTK 程序,当点击“画圆”按钮时画圆,当点击“画线”按钮时画线。我应该只有一张图。但是我在面板中得到了两个图表。我只想要一个显示,另一个消失。以下是代码:
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Box.H>
using namespace std;
int flag = 0;
class Drawing : public Fl_Box {
void draw() {
fl_color(255, 0, 0);
int x, y, x1, y1;
if (flag == 1) {
double radius = 100;
x = (int)(w() / 2);
y = (int)(h() / 2);
fl_circle(x, y, radius);
}
else if (flag == -1) {
x = (int)(w() / 4);
y = (int)(h() / 4);
x1 = (int)(w() *3/ 4);
y1 = (int)(h() *3/ 4);
fl_line(x, y, x1, y1);
}
}
public:
Drawing(int X, int Y, int W, int H) : Fl_Box(X, Y, W, H) {}
};
Drawing* d;
void circle_cb(Fl_Widget*, void*) {
flag = 1;
fl_overlay_clear();
d->redraw();
} // end sumbit_cb
void line_cb(Fl_Widget*, void*) {
flag = -1;
fl_overlay_clear();
d->redraw();
} // end clear_cb
int main(int argc, char** argv) {
Fl_Window* window = new Fl_Window(600, 550); // create a window, originally(400,400)
Drawing dr(0, 0, 600, 600);
d = &dr;
Fl_Button *b, *c;
b = new Fl_Button(150, 80, 100, 25, "&Draw Circle");
b->callback(circle_cb);
c = new Fl_Button(350, 80, 100, 25, "&Draw Line");
c->callback(line_cb);
window->end(); //show the window
window->show(argc, argv);
return Fl::run();
}
我已经使用 fl_overlay_clear() 来清除图表。但是它不起作用。任何帮助将不胜感激。
在你的 handle() 方法 line_cb()
中,circle_cb()
应该调用 window()->make_current()
然后 fl_overlay_rect()
在 FL_DRAG
事件之后,并且应该调用 fl_overlay_clear()
在 FL_RELEASE event
之后。 Refer了解更多详情
您的程序中有几个问题需要解决,但首先像您一样使用 draw() 方法基本上是正确的。但是,使用 fl_overlay_clear();没用的,可以去掉。
我的解决方案:您的小部件没有纯色背景 (boxtype),即您的绘制方法一遍又一遍地在背景上绘制 w/o 清除它。有几种方法可以解决这个问题,但如果您想了解会发生什么,请先尝试这个:在 window->show(argc, argv);
之前添加 window->resizable(window);
,再次 运行 程序并调整 window 的大小.您会注意到之前的绘图消失了,只剩下一张绘图。那是因为当你调整小部件的大小时背景被清除了。
下一步:添加实心框类型:
d = &dr;
d->box(FL_DOWN_BOX);
并在 draw()
方法的开头添加 Fl_Box::draw();
。
如果您这样做,您可能会注意到当您单击其中一个按钮时,您的按钮会消失 - 因为您的按钮 在 您的 Drawing
区域中.我修复的最后一件事是更正按钮的坐标并放大 window(无论如何它太小无法覆盖整个 Drawing
)。这是我的完整结果:
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Box.H>
using namespace std;
int flag = 0;
class Drawing : public Fl_Box {
void draw() {
Fl_Box::draw();
fl_color(255, 0, 0);
int x, y, x1, y1;
if (flag == 1) {
double radius = 100;
x = (int)(w() / 2);
y = (int)(h() / 2);
fl_circle(x, y, radius);
} else if (flag == -1) {
x = (int)(w() / 4);
y = (int)(h() / 4);
x1 = (int)(w() * 3 / 4);
y1 = (int)(h() * 3 / 4);
fl_line(x, y, x1, y1);
}
}
public:
Drawing(int X, int Y, int W, int H)
: Fl_Box(X, Y, W, H) {}
};
Drawing *d;
void circle_cb(Fl_Widget *, void *) {
flag = 1;
// fl_overlay_clear(); // not useful
d->redraw();
} // end sumbit_cb
void line_cb(Fl_Widget *, void *) {
flag = -1;
// fl_overlay_clear(); // not useful
d->redraw();
} // end clear_cb
int main(int argc, char **argv) {
Fl_Window *window = new Fl_Window(600, 660); // create a window, originally(400,400)
Drawing dr(0, 60, 600, 600); // FIXED
d = &dr;
d->box(FL_DOWN_BOX); // ADDED
Fl_Button *b, *c;
b = new Fl_Button(150, 20, 100, 25, "&Draw Circle"); // FIXED
b->callback(circle_cb);
c = new Fl_Button(350, 20, 100, 25, "&Draw Line"); // FIXED
c->callback(line_cb);
window->end(); // show the window
window->resizable(window); // ADDED
window->show(argc, argv);
return Fl::run();
}
我相信这可以满足您的需求。
PS:可以在我们的网站上找到官方 FLTK 支持论坛 https://www.fltk.org/ and the direct link to the user forum (Google Groups) is https://groups.google.com/g/fltkgeneral
只是对 Albrecht 如此完美的补充:FLTK 绘图坐标是相对于 window,而不是相对于小部件的。您可能希望通过小部件的 x()
和 y()
坐标偏移绘图。