我正在进行实时绘图应用程序,其中数据流将在屏幕上绘制。在前面使用gtkmm2时,我使用了一个自定义小部件(从Gtk::Bin派生),其中我有一个成员函数,它创建一个cairo上下文并进行绘图。
现在,使用gtkmm3,我无法用除on_draw以外的任何方法来绘图。以下是我的自定义绘制方法主体的样子
Gtk::Allocation oAllocation = get_allocation();
Glib::RefPtr <Gdk::Window> refWindow = get_window();
Cairo::RefPtr <Cairo::Context> refContext =
refWindow->create_cairo_context();
refWindow->begin_paint_rect(oAllocation); //added later
refContext->save();
refContext->reset_clip();
refContext->set_source_rgba(1,
1,
1,
1);
refContext->move_to(oAllocation.get_x(),
oAllocation.get_y());
refContext->line_to(oAllocation.get_x()
+ oAllocation.get_width(),
oAllocation.get_y()
+ oAllocation.get_height());
refContext->stroke();
refContext->restore();
refWindow->end_paint();最初,我从Gtk::DrawingArea派生类,然后在添加begin_paint_rect调用时尝试使用Gtk::Bin。
禁止在on_draw以外的任何地方画画吗?
发布于 2020-09-28 23:25:42
对于一个情节(或任何相当复杂的绘图),我建议使用一个缓冲区;我失去了一个月的生命,因为我读到gtkmm3可以缓冲,这样就不再需要使用“双重缓冲”了(与gtkmm2不同),但它并不那么简单(读:这不是真的)。
所以,你应该做的就是画到你自己的表面上,每次你改变一些叫做queue_draw_region或queue_draw_area的东西。
然后在on_draw中获取剪辑矩形的列表,并将这些矩形从您的专用曲面复制到传递给on_draw函数的cr中。Cairo通常会做完全相同的事情(或者他们所声称的),将您刚刚复制的内容复制到屏幕上;因此您应该关闭它(这应该是我所读到的)。
您不能使用Cairo的缓冲区的原因是因为它没有保留该缓冲区;您得到的是一些损坏的表面,因此您不得不重新绘制剪辑矩形列表中的所有内容。如果您(您的应用程序)是唯一进行更改(如您的queue_draw_*调用)的应用程序,那么就不会太糟糕了:然后您可以设置一个标志,使需要重绘的部分无效,并且只需将绘制推迟到on_draw。但是有时会因为其他原因而调用on_draw,例如,当您打开超出绘图区域的菜单时。我认为这是一个错误(或设计错误),但这就是它的方式。其结果是,除非查看剪辑矩形列表,否则您无法知道必须重新绘制什么;这使得只绘制区域的一部分变得非常困难,除非您的绘图是由许多独立的矩形(例如,国际象棋棋盘)组成的。唯一可行的方法是将图像的完整副本保存在内存中(您的专用图面),并在on_draw中从那里复制剪辑矩形列表。
发布于 2019-12-20 08:22:58
禁止在除on_draw以外的任何地方画画吗?
基本上:是的。
这样做的想法是,当您想要重新绘制时调用gtk_widget_queue_draw()或gtk_widget_queue_draw_area()。
https://stackoverflow.com/questions/59386569
复制相似问题