FLTK:绘制另一个图形时清除一个图形
Posted
技术标签:
【中文标题】FLTK:绘制另一个图形时清除一个图形【英文标题】:FLTK: Clearing a graph when drawing another 【发布时间】:2021-12-16 00:26:59 【问题描述】:我编写了一个简单的 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() 来清除图形。但是它不起作用。任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:只是对 Albrecht 完美表述的快速补充:FLTK 绘图坐标是相对于窗口的,而不是相对于小部件的。您可能希望通过小部件的x()
和y()
坐标来偏移绘图。
【讨论】:
好收获。我一定错过了。【参考方案2】:你的程序有几个问题需要修复,但首先像你做的那样使用draw()方法基本上是正确的。但是,使用 fl_overlay_clear();没用,你可以去掉。
我的解决方案:您的小部件没有纯色背景(boxtype),即您的 draw 方法一遍又一遍地在背景上绘制而不清除它。有几种方法可以解决这个问题,但如果你想了解会发生什么,请先试试这个:在window->show(argc, argv);
之前添加window->resizable(window);
,再次运行程序并调整窗口大小。您会注意到上一张图消失了,只留下一张图。那是因为当您调整小部件的大小时,背景会被清除。
下一步:添加一个solid boxtype:
d = &dr;
d->box(FL_DOWN_BOX);
并在 draw()
方法的开头添加 Fl_Box::draw();
。
如果您这样做,您可能会注意到当您单击其中一个按钮时按钮会消失 - 因为您的按钮在您的Drawing
区域内。我修复的最后一件事是更正按钮的坐标并放大窗口(无论如何它太小而无法覆盖整个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/ 上找到,用户论坛(Google Groups)的直接链接是https://groups.google.com/g/fltkgeneral
【讨论】:
非常感谢。这就是我想要的。【参考方案3】:在您的 handle() 方法中,line_cb()
和 circle_cb()
应该在 FL_DRAG
事件之后调用 window()->make_current()
和 fl_overlay_rect()
,并且应该在 FL_RELEASE event
之后调用 fl_overlay_clear()
。 Refer了解更多详情
【讨论】:
感谢您回答我的问题。你能说得更详细些吗? 嗯,我认为这个答案没有帮助,因为 OP 正确使用了类的虚拟 draw() 方法。我会发布另一个答案。以上是关于FLTK:绘制另一个图形时清除一个图形的主要内容,如果未能解决你的问题,请参考以下文章