如何在Gtk :: DrawingArea区域绘制一个新行,同时存在已经绘制的前一行?(How to draw a new line on Gtk::DrawingArea area, while p

编程入门 行业动态 更新时间:2024-10-25 05:12:37
如何在Gtk :: DrawingArea区域绘制一个新行,同时存在已经绘制的前一行?(How to draw a new line on Gtk::DrawingArea area, while peristing previous lines that have already been drawn?)

我在Ubuntu 12.04 LTS 32位上使用带有gtkmm3的GNU工具链的C ++ 11。 我一直在玩gtkmm 3编程中的 gtkmm3的一些例子。

基于17.2.1.Example那里,我继承自Gtk::DrawingArea ( MyDrawingArea here)并覆盖了on_draw()事件处理程序,如下所示:

MyDrawingArea.hpp

... protected: bool on_draw ( const Cairo::RefPtr<Cairo::Context>& cr ) override;

MyDrawingArea.cpp

bool MyDrawingArea::on_draw( const Cairo::RefPtr<Cairo::Context>& cr ) { Gtk::Allocation allocation = get_allocation( ); const int width = allocation.get_width( ); const int height = allocation.get_height( ); int coord1{ height - 3 }; cr->set_line_width( 3.0 ); this->get_window( )->freeze_updates( ); cr->set_source_rgb( 0, 0.40, 0.60 ); cr->move_to( 0, coord1 ); cr->line_to( width, coord1 ); cr->stroke( ); cr->set_source_rgb( 1, 0.05, 1 ); cr->move_to( mXStart, coord1 ); cr->line_to( mXStart, mYAxis * 1.5 ); cr->show_text( to_string( mYAxis ) ); cr->stroke( ); mXStart += 5; this->get_window( )->thaw_updates( ); return true; }

我的目标是根据我在一个小测试应用程序中进行的计算绘制一个简单的条形图,其想法是每次调用on_draw()事件时,下一个条形图将在mXAxis上mXAxis移动5个单位,并且将根据新的mYaxis值绘制垂直线,该值基于新计算的结果计算。

当我想重新绘制我的图形并触发MyDrawingArea :: on_draw()事件时,我在计算完成后从我的应用程序调用MyDrawingArea.show_all(),并设置了新的x和y轴。

但是,这并不像我预期的那样工作: MyDrawingArea.show_all()使整个绘图窗口无效并从头开始绘制: 新的图形线显示在适当的位置 ,但先前的图形线将被删除。 我也尝试了MyDrawingArea.queue_draw() ,它具有相同的效果。 但我想保留以前的图形结果,这样我就可以得到计算结果的轮廓,因为我用不同的值计算。

这个实现也导致了我的图形上的底线(图中我的x轴) - 由我的代码示例中的第一个stroke()调用绘制,在每次调用on_draw()时重新渲染 - 尽管这不应该是necassary因为这一行在MyDrawingArea的生命周期中持续存在 - 不应该像我的代码当前那样在每个新的on_draw()事件中使其无效并重新绘制它,因为我还没有找到办法处理这个(事情。

我对开罗很新,所以我确定我可能完全错了,但明确的,面向任务的文档似乎很少 - 没有找到任何解释如何做到这一点,虽然我确定它很简单。

我需要做什么才能在Gtk::DrawingArea上绘制一个新行,同时保留先前已经在先前遍历中绘制的图形行,并建立将在Gtk::DrawingArea小部件的生命周期中保留的图形元素。 显然,使用queue_draw() show_all()或queue_draw()并在on_draw()事件中完成所有操作都不是on_draw()的方法。

I am using C++11 with GNU tool chain with gtkmm3, on Ubuntu 12.04 LTS 32 bit. I have been playing wtih some of the examples for gtkmm3 in Programming with gtkmm 3.

Based on 17.2.1.Example there, I inherited from Gtk::DrawingArea (MyDrawingArea here) and overrode the on_draw() event handler as follows:

MyDrawingArea.hpp

... protected: bool on_draw ( const Cairo::RefPtr<Cairo::Context>& cr ) override;

MyDrawingArea.cpp

bool MyDrawingArea::on_draw( const Cairo::RefPtr<Cairo::Context>& cr ) { Gtk::Allocation allocation = get_allocation( ); const int width = allocation.get_width( ); const int height = allocation.get_height( ); int coord1{ height - 3 }; cr->set_line_width( 3.0 ); this->get_window( )->freeze_updates( ); cr->set_source_rgb( 0, 0.40, 0.60 ); cr->move_to( 0, coord1 ); cr->line_to( width, coord1 ); cr->stroke( ); cr->set_source_rgb( 1, 0.05, 1 ); cr->move_to( mXStart, coord1 ); cr->line_to( mXStart, mYAxis * 1.5 ); cr->show_text( to_string( mYAxis ) ); cr->stroke( ); mXStart += 5; this->get_window( )->thaw_updates( ); return true; }

My goal is to draw a simple bar graph based on a calculation I do in a little test application, the idea being that each time the on_draw() event is called, the next bar would be moved 5 units to the right on mXAxis and a vertical line would be drawn based on the new mYaxis value, which is computed based on the results of the new calculation.

When I want to repaint my graph and trigger the MyDrawingArea::on_draw() event, I call MyDrawingArea.show_all() from my application after the calculation has completed, and new x and y axes have been set.

However, this does not work as I expected: MyDrawingArea.show_all() invalidates the entire drawing window and draws from scratch: the new graph line appears in its proper place, but the previous ones are erased. I also tried MyDrawingArea.queue_draw(), which had the same effect. But I want to persist the previous graph results so I can get a profile of the calculation results, as I calculate with different values.

This implementation is also causing the bottom line on my graph (my x axis on the graph)- drawn by the first stroke() call in my code example, to be rendered anew on each call to on_draw() - although this should not be necassary since this line persists for the lifetime of MyDrawingArea - it should not be necessary to invalidate and then re-draw it on each new on_draw() event, as my code is currently doing, because I am haven't yet found a way to handle this.

I am very new to Cairo, so I'm sure I'm probably doing this completely wrong, but explicit, task-oriented documentation appears to be sparse - have not found anything that explains how to do this, although I'm sure it is quite simple.

What do I need to do to draw a new line on Gtk::DrawingArea, while persisting previous graph lines that have already been drawn on previous passes, and establish graphics elements that will persist for the lifetime of the Gtk::DrawingArea widget. Obviously using show_all() or queue_draw() and doing it all in the on_draw() event is not the way to go.

最满意答案

通常,您必须绘制整个窗口小部件,并且Cairo会将绘图剪切到预定义的脏区域。 有关性能提示,请参阅“GtkWidget :: draw”信号的GTK参考手册:

信号处理程序将获得一个cr,其中一个剪辑区域已经设置到小部件的脏区域,即需要重新绘制的区域。 想要避免完全重绘自身的复杂小部件可以使用gdk_cairo_get_clip_rectangle()获取剪辑区域的完整范围,或者可以使用cairo_copy_clip_rectangle_list()获得更细粒度的脏区域表示。

因此,您可以使用gtk_widget_queue_draw_area()仅重绘所需的区域。

In general, you must draw the entire widget and Cairo will clip the drawing to the predefined dirty region. See also GTK reference manual for the "GtkWidget::draw" signal for performance tips:

The signal handler will get a cr with a clip region already set to the widget's dirty region, i.e. to the area that needs repainting. Complicated widgets that want to avoid redrawing themselves completely can get the full extents of the clip region with gdk_cairo_get_clip_rectangle(), or they can get a finer-grained representation of the dirty region with cairo_copy_clip_rectangle_list().

So you may be able to redraw only the region you want with gtk_widget_queue_draw_area().

更多推荐

本文发布于:2023-08-07 22:48:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1466434.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:区域   如何在   draw   DrawingArea   line

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!