开发者

Segfault when creating smartpointer on CairoContext

开发者 https://www.devze.com 2023-04-13 06:57 出处:网络
I got some problems when creating a Cairo::RefPtr on a Cairo-Context. I really can\'t imagine why this segfaults, except the pointer ist pointing on something completely wrong.

I got some problems when creating a Cairo::RefPtr on a Cairo-Context. I really can't imagine why this segfaults, except the pointer ist pointing on something completely wrong.

This is my code.

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:开发者_C百科:Main::run(window);

    }

And this is what GDB says:

Starting program: /home/marian/Desktop/C++/Langton/Langton [Thread debugging using libthread_db enabled]

Program received signal SIGSEGV, Segmentation fault. 0xb7be852e in Gdk::Window::create_cairo_context() () from /usr/lib/libgdkmm-3.0.so.1

I compiled this with gcc (GCC) 4.6.1 20110819 (prerelease).

Thanks in advance


Gtk::Widget::get_window() returns a null Glib::RefPtr, since the widget has not been realized just yet.

Based on the GtkDrawingArea documentation, you need to hook onto the "draw" signal to handle drawing, where your Cairo context is already created and handed to you. Going back to the Gtkmm reference, you would use Gtk::Widget::signal_draw() to hook onto that, or you could overload the virtual on_draw() function to handle your drawing.

Additionally, you also need to call .show() on each widget, i.e. your DrawingArea and your Window, and call ccontext->stroke() to get the line actually drawn.

The result would look something like:

#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;
}

or alternatively:

#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;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号