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() 坐标偏移绘图。