C ++ FLTK,创建一个圆角框

时间:2014-05-08 08:11:52

标签: c++ fltk

问题是: 画一个圆角的方框。定义一个类Box,由四行和四个弧组成。 所以我为这个练习编写了以下代码:

#include <Simple_window.h>
Simple_window win(Point(100,100), 600,400, "semi-ellipse");

struct Box: Shape{

    Box(Point p, int ww, int hh): w(ww), h(hh) 
        { add(Point(p.x-ww,p.y-hh));  }

    void d_l() const        //creating 4 lines
     {
        Line hrz1 (Point(150,100), Point(400,100));
        Line hrz2 (Point(150,300), Point(400,300));
        Line ver1 (Point(507,150), Point(507,250));
        Line ver2 (Point(41,150), Point(41,250));

        win.attach(hrz1);
        win.attach(hrz2);
        win.attach(ver1);
        win.attach(ver2);
     }

    void draw_lines() const      //creating 4 arcs
    {
        fl_arc(point(0).x,point(0).y,w,h,30,90);
        fl_arc(point(0).x,point(0).y,w,h,270,330);
        fl_arc(point(0).x,point(0).y,w,h,90,150);
        fl_arc(point(0).x,point(0).y,w,h,210,270);
    }

private:
    int w;
    int h;
};

int main()
{
    using namespace Graph_lib; 

    Box b(Point(100,100),100,50);
    win.attach(b);
    win.wait_for_button();
}

当我跑步时,我遇到了这个例外:

  

test.exe中0x757FE9D7(ole32.dll)的未处理异常:0xC0000005:访问冲突读取位置0x00000004。

我知道这是指在全球状态下声明Simple_window win(Point(100,100), 600,400, "semi-ellipse");。但我这样做是因为我不得不这样做。问题是如何在任一部分(b函数和Simple_window win struct)中将行和对象(此处main())附加到Box

3 个答案:

答案 0 :(得分:1)

看起来它是由全球创造的胜利引起的。我从未运行过FLTK程序,其中在main之前创建了任何图形,但我猜测有时图形库需要一些东西到位,所以最好在main之后使用它们。

你能做些什么呢?如果win被声明为指针并在main而不是main main中创建,那么你就不会发生崩溃。

...
Simple_window* win;
struct Box: Shape
{
  ...
   win->...
   ...
}


int main()
{
    win = new Simple_window(Point(100, 100), 600, 400, "semi-ellipse");
    Box b ...
    win->attach ...
    win->wait ...
    delete win;
}

答案 1 :(得分:1)

根本不需要在全球空间放置任何东西。您希望将信息传递给需要它们的类,而不是在使用它之前需要在全局范围内声明的所有内容。

我在这里写的内容会修改你的Box类,以便它还有一个私有成员变量,它是指向Simple_window类的指针。修改构造函数,以便在构造Box b时,必须向它发送指向它将被绘制的Simple_window的指针。执行此操作时,将为指针指定指向当时声明的Simple_Window win

的指针
#include <Simple_window.h>


struct Box: Shape{

private:
    int w;
    int h;
    Simple_window* window;
public:

    Box(Point p, int ww, int hh,Simple_window* win_): w(ww), h(hh),window(win_)
    { add(Point(p.x-ww,p.y-hh));  }

    void d_l() const        //creating 4 lines
    {
        Line hrz1 (Point(150,100), Point(400,100));
        Line hrz2 (Point(150,300), Point(400,300));
        Line ver1 (Point(507,150), Point(507,250));
        Line ver2 (Point(41,150), Point(41,250));

        window->attach(hrz1);
        window->attach(hrz2);
        window->attach(ver1);
        window->attach(ver2);
    }

    void draw_lines() const      //creating 4 arcs
    {
        fl_arc(point(0).x,point(0).y,w,h,30,90);
        fl_arc(point(0).x,point(0).y,w,h,270,330);
        fl_arc(point(0).x,point(0).y,w,h,90,150);
        fl_arc(point(0).x,point(0).y,w,h,210,270);
    }


};

int main()
{
    using namespace Graph_lib;
    Simple_window* win = new Simple_window(Point(100,100), 600,400, "semi-ellipse");
    Box b(Point(100,100),100,50,win);
    win->attach(b);
    win->wait_for_button();
}

答案 2 :(得分:0)

您的行是硬编码的,与构造函数参数无关。它们可以直接使用FLTK库绘制,类似于弧,并放置在继承自类Shape和覆盖函数void draw_lines() const的内部。然后你不需要将窗口对象作为指针。

可能的实施方式是:

Box::Box(Point p, int w, int h)
    : width(w), height(h)
{ 
    add(Point(p.x - w, p.y - h));
}

void Box::draw_lines() const
{
    // draw lines with reduced length to adapt for the arcs
    if (color().visibility())
    {
        // upper horizontal
        fl_line(point(0).x + width/4, point(0).y, point(0).x + (3./4.) * width, point(0).y);
        // lower horizontal
        fl_line(point(0).x + width/4, point(0).y + height, point(0).x + (3./4.) * width, point(0).y + height);
        // left vertical 
        fl_line(point(0).x, point(0).y + height/4, point(0).x, point(0).y + (3./4.)*height);
        // right vertical 
        fl_line(point(0).x + width, point(0).y + height/4, point(0).x + width, point(0).y + (3./4.) * height);
    }

    // draw arcs
    if(color().visibility())
    { 
        fl_color(fill_color().as_int());
        // upper left arc
        fl_arc(point(0).x, point(0).y, width/2, height/2, 90, 180); 
        // upper right arc
        fl_arc(point(0).x + width/2, point(0).y, width/2, height/2, 0, 90);
        // down right arc
        fl_arc(point(0).x + width/2, point(0).y + height/2, width/2, height/2, 270, 0); 
        // down left arc
        fl_arc(point(0).x , point(0).y + height/2, width/2, height/2, 180, 270); 
    }
}