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-&gt;show(argc, argv); 之前添加window-&gt;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()-&gt;make_current()fl_overlay_rect(),并且应该在 FL_RELEASE event 之后调用 fl_overlay_clear()。 Refer了解更多详情

【讨论】:

感谢您回答我的问题。你能说得更详细些吗? 嗯,我认为这个答案没有帮助,因为 OP 正确使用了类的虚拟 draw() 方法。我会发布另一个答案。

以上是关于FLTK:绘制另一个图形时清除一个图形的主要内容,如果未能解决你的问题,请参考以下文章

vb 执行Cls语句,将清除窗体上用Print方法输出的内容、用图形方法绘制的图形以及窗体

在 OpenGL 中绘制 3d 图形的最有效方法是啥?

在数组中存储可变数量的点

如何将canvas所画的图形清除或者删除掉?

Canvas 使用

Win10系列:JavaScript图形