在CairoContext上创建smartpointer时出现Segfault

Segfault when creating smartpointer on CairoContext

本文关键字:Segfault smartpointer CairoContext 创建      更新时间:2023-10-16

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

这是我的代码。

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[使用libthread_db调试]

程序收到信号SIGSEGV,分段错误。0 xb7be852eGdk::Window::create_cairo_context() () from/usr/lib/libgdkmm-3.0.so.1

我用gcc (gcc) 4.6.1 20110819 (pre - release)编译了这个。

Thanks in advance

Gtk::Widget::get_window()返回null Glib::RefPtr,因为小部件还没有实现。

根据GtkDrawingArea文档,您需要挂钩到"draw"信号来处理绘图,在这里您的Cairo上下文已经创建并交给了您。回到Gtkmm参考,您可以使用Gtk::Widget::signal_draw()来挂钩它,或者您可以重载虚拟的on_draw()函数来处理您的绘图。

此外,你还需要在每个小部件上调用。show(),即你的DrawingArea和你的Window,并调用ccontext->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;
}