Re: the right way to draw in a drawingarea



On Tue, 11 Oct 2005 03:16:54 -0500, Paul Davis wrote:

> Not at all.
> 
> My bad about that method, its actually queue_draw()
> http://www.gtkmm.org/docs/gtkmm-2.4/docs/reference/html/classGtk_1_1Widget.html#a153
> 
> I can't really explain this too well cause I haven't really read all the 
> specifics on how gtk does its drawing of widgets and the such.  
> Basically, you want to let gtk decide when it needs an update.  
> queue_draw just says, please update now.  When you get into repainting 
> the entire screen you'll get the flashes you menitoned.
> 
> Oh and just to make sure, you aren't doing anything silly like clearing 
> the widget with something like
> DrawRectangle( background, 0, 0, WIDTH, HEIGHT )  (obviously not a real 
> function call, just illustrating the point) cause that would
> also introduce flickering.
> 
> The way to do this is to make your on_expose_event draw the box.
> 
> ie:
> 
> void on_expose_event( GdkEventExpose ev )
> {
>     //Draw background pixbuf.
>     update_display() ;
> 
>     //draw rectangle
>     if( left > 0 && top > 0 && right > 0 && bot > 0 )
>          Darea->get_window()->draw_rectangle(gc_, 0, left, top,
>                 right-left, bot-top);
> }
> 
> Then add ( and connect this to the button press signal obviously. )
> on_Darea_button_press_event( GdkEventButton *ev )
> {
>        if( ev->state & Gdk::BUTTON1_MASK )
>        {
>           left = ev->x ;
>           top = ev->y ;
> 
>           right = ev->x ;
>           bottom = ev->y ;
>        }
>        else
>        {
>              //Erase rectangle.
>              left = -1 ;
>              top = -1 ;
> 
>              right = -1 ;
>              bottom = -1 ;
>        }
> 
>        Darea->queue_draw() ;
> }
> 
> And then in your
> on_Darea_motion_notify_event( GdkEventButton* ev )
> {
>     right=ev->x;
>     if(left>right) swap(left,right);
>     bot=ev->y;
>     if(top>bot) swap(top,bot);
> 
>     Darea->queue_draw() ;
> } 

Darea->queue_draw() works in mysterious ways, but it definitely works
better. By not calling queue_draw() rather than my custom update_display()
(which renders the entire pixbuf into the background) from the
motion_notify_event() handler, stops the flickering: neither the
background image nor the already drawn shapes flicker anymore. 

And the rectangle or the ellipse being drawn by dragging with the mouse
does update dynamically, as I want it to. This was what I didn't
understand - how it was possible to draw a changing rectangle without
repainting the pixbuf into the background from within
motion_notify_event(). I still don't understand how queue_draw() does it,
but I'm glad it works.

Indeed, not hard to fix, if you know about the right function calls. Or if
you ask the right people. Thank you all for the help.






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]