在CairoContext上创建smartpointer时的Segfault

时间:2011-10-14 17:59:43

标签: c++ segmentation-fault cairo gtkmm

在Cairo-Context上创建Cairo :: RefPtr时遇到了一些问题。 我真的无法想象为什么这个段错误,除了指针指向完全​​错误的东西。

这是我的代码。

int main(int argc, char * argv[])
    {
    Gtk::Main kit(argc, argv);
    Gtk::Window window;
    Gtk::DrawingArea drawarea;
    window.add(drawarea);
    Cairo::RefPtr<Cairo::Context> ccontext = drawarea.get_window()->create_cairo_context();
    Gtk::Allocation allocation = drawarea.get_allocation();
    const int width = allocation.get_width();
    const int height = allocation.get_height();
    ccontext->set_source_rgb(1.0, 0.0, 0.0);
    ccontext->set_line_width(2.0);
    ccontext->move_to(0,0);
    ccontext->line_to(width, height);

    Gtk::Main::run(window);

    }

这就是GDB所说的:

  

启动程序:/ home / marian / Desktop / C ++ / Langton / Langton [Thread   使用libthread_db启用调试]

     

编程接收信号SIGSEGV,分段故障。 0xb7be852e in   来自/usr/lib/libgdkmm-3.0.so.1的Gdk :: Window :: create_cairo_context()()

我用gcc(GCC)4.6.1 20110819(预发布)编译了这个。

提前致谢

1 个答案:

答案 0 :(得分:2)

Gtk :: Widget :: get_window()返回一个空的Glib :: RefPtr,因为该小部件尚未实现。

基于GtkDrawingArea documentation,您需要挂钩“绘制”信号来处理绘图,其中您的Cairo上下文已经创建并交给您。回到Gtkmm reference,你可以使用Gtk :: Widget :: signal_draw()挂钩,或者你可以重载虚拟的on_draw()函数来处理你的绘图。

此外,您还需要在每个小部件上调用.show(),即您的DrawingArea和您的Window,并调用ccontext-&gt; stroke()来获取实际绘制的行。

结果看起来像是:

#include <gtkmm.h>

bool draw (const Cairo::RefPtr<Cairo::Context> &ccontext, Gtk::DrawingArea *drawarea)
{
    Gtk::Allocation allocation = drawarea->get_allocation();
    const int width = allocation.get_width();
    const int height = allocation.get_height();
    ccontext->set_source_rgb(1.0, 0.0, 0.0);
    ccontext->set_line_width(2.0);
    ccontext->move_to(0,0);
    ccontext->line_to(width, height);
    ccontext->stroke ();

    return true;
}

int main(int argc, char * argv[])
{
    Gtk::Main kit(argc, argv);
    Gtk::Window window;
    Gtk::DrawingArea drawarea;

    drawarea.signal_draw ().connect (sigc::bind (sigc::ptr_fun (&draw),
                                                 &drawarea));
    window.add(drawarea);
    window.show_all ();

    Gtk::Main::run(window);
    return 0;
}

或者:

#include <gtkmm.h>

class LineBox : public Gtk::DrawingArea
{
protected:
    virtual bool on_draw (const Cairo::RefPtr<Cairo::Context> &ccontext);
};

bool LineBox::on_draw (const Cairo::RefPtr<Cairo::Context> &ccontext)
{
    Gtk::Allocation allocation = get_allocation();
    const int width = allocation.get_width();
    const int height = allocation.get_height();
    ccontext->set_source_rgb(1.0, 0.0, 0.0);
    ccontext->set_line_width(2.0);
    ccontext->move_to(0,0);
    ccontext->line_to(width, height);
    ccontext->stroke ();

    return true;
}

int main(int argc, char * argv[])
{
    Gtk::Main kit(argc, argv);
    Gtk::Window window;
    LineBox drawarea;

    window.add(drawarea);
    window.show_all ();

    Gtk::Main::run(window);
    return 0;
}
相关问题