在 CairoContext 上创建智能指针时出现段错误

发布于 2024-12-10 02:58:03 字数 1037 浏览 3 评论 0原文

在 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 [线程 使用 libthread_db 进行调试已启用]

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

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

提前致谢

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::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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

与酒说心事 2024-12-17 02:58:03

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

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

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

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文