LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

How to reduce the blink when redrawing a plot?

Hello,

 

Through XOR operation to draw an arc on the canvas control continuously, it will blink. Is there any method to reduce the blink occurring?

 

David

0 Kudos
Message 1 of 8
(4,332 Views)

yes, you can hide the control before drawing and unhide it afterwards. Without draw events occuring during the 'hidden period' the display will not be updated and hence you will not notice the hide/unhide process 

0 Kudos
Message 2 of 8
(4,326 Views)

Hi Walfgang,

 

As your prompted, I have changed the code as the follows:

....

startAng = 0;

 

while (TEUE)

{

            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_PEN_COLOR, MakeColor(199, 172, 223));  
            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_PEN_MODE, VAL_XOR_MODE);
            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_DRAW_POLICY, VAL_MARK_FOR_UPDATE);
            
            SetCtrlAttribute(radarPanel, RADARPANEL_CANVAS, ATTR_VISIBLE, 0);  
            CanvasDrawArc(radarPanel, RADARPANEL_CANVAS, MakeRect(0,0,height+6, width+6), startAng, 150, VAL_DRAW_FRAME_AND_INTERIOR);
            SetCtrlAttribute(radarPanel, RADARPANEL_CANVAS, ATTR_VISIBLE, 1);


            Delay(0.2);


            SetCtrlAttribute(radarPanel, RADARPANEL_CANVAS, ATTR_VISIBLE, 0);
            CanvasDrawArc(radarPanel, RADARPANEL_CANVAS, MakeRect(0,0,height+6, width+6), startAng, 150, VAL_DRAW_FRAME_AND_INTERIOR);
            SetCtrlAttribute(radarPanel, RADARPANEL_CANVAS, ATTR_VISIBLE, 1);

            startAng += 10;

...

}

 

This code phase is in a thread. But the effects looks that it still will blink.

 

David

0 Kudos
Message 3 of 8
(4,322 Views)

David,

 

A couple of comments:

 

1. Wolfgang's suggestion was to hide the control while you're drawing both arcs. You are hiding it and showing for each arc. You shouldn't do that.

 

2. Since you have the canvas draw policy set to MARK_FOR_UPDATE, you should not need to hide the canvas at all. The rationale of using MARK_FOR_UPDATE is the same as hiding the control: the canvas control will wait until events are processed before drawing anything.

 

So why are you still seeing flashing?

 

3. You mention that this is running in a separate thread. That's actually relevant in this case, because if the panel that has the canvas was created by the main thread, then it will try to draw whenever the main thread is processing events. Which probably happens often enough during your 0.2 second delay.

 

Your only solution is to disable event processing for the main thread in between the time when the two arcs are drawn. In my opinion, the best way to do this is to run this code in the main thread, by calling PostDeferredCall or PostDeferredCallToThread from this function to ensure that it runs in the main thread instead. You can then control more easily whether or not you process events in between the drawing of the two arcs.

 

Luis

Message 4 of 8
(4,285 Views)

Hi Luis,

 

Thank you for your reply. I'll try it as your suggestion then tell you the result.

 

 

David

0 Kudos
Message 5 of 8
(4,243 Views)

Hi Luis,

 

As your advise, I have added a timer control in the application, the drawing code is involved in its callback function, like the follows:

 

int CVICALLBACK DrawCanvas(int panelHandle, int controlID, int event, void *callbackData, int eventData1, int eventData2)
{
    static int startAng = 0;  
    
    
    switch (event)
    {
        case EVENT_TIMER_TICK:
            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_PEN_COLOR, MakeColor(199, 172, 223));  
            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_PEN_MODE, VAL_XOR_MODE);
            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_DRAW_POLICY, VAL_MARK_FOR_UPDATE);


            CanvasDrawArc(radarPanel, RADARPANEL_CANVAS, MakeRect(0,0,height+6, width+6), startAng, 150, VAL_DRAW_FRAME_AND_INTERIOR);


            CanvasDrawArc(radarPanel, RADARPANEL_CANVAS, MakeRect(0,0,height+6, width+6), startAng, 150, VAL_DRAW_FRAME_AND_INTERIOR);


            startAng += 10;
            if (startAng == 3600)
            {
                startAng = 0;
            }
            
            break;
            
    }
    return 0;
}

 

the timer interval is 0.2s, but for each time ticker event, I can not see the drawing. Please advise what pen mode should I use. Thanks.

 

David

0 Kudos
Message 6 of 8
(4,219 Views)

Hi Luis,

 

The problem has been resolved by the follows codeing:

 

int CVICALLBACK DrawCanvas(int panelHandle, int controlID, int event, void *callbackData, int eventData1, int eventData2)
{
    static int startAng = 0;
    static int counter = 1;
    
    
    switch (event)
    {
        case EVENT_TIMER_TICK:
            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_PEN_COLOR, MakeColor(199, 172, 223));  
            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_PEN_MODE, VAL_XOR_MODE);
            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_DRAW_POLICY, VAL_MARK_FOR_UPDATE);
            if (counter % 2 != 0)
            {
                CanvasDrawArc(radarPanel, RADARPANEL_CANVAS, MakeRect(0,0,height+6, width+6), startAng, 150, VAL_DRAW_FRAME_AND_INTERIOR);
                
                counter ++;
            }
            else
            {
                CanvasDrawArc(radarPanel, RADARPANEL_CANVAS, MakeRect(0,0,height+6, width+6), startAng, 150, VAL_DRAW_FRAME_AND_INTERIOR);
                counter --;
                startAng += 10;
                if (startAng == 3600)
                {
                    startAng = 0;
                }
            

            }
            break;
            
    }
    return 0;
}

using the counter variable. but is there any way to make the drawing seems continuous?

 

David

0 Kudos
Message 7 of 8
(4,213 Views)

The Problem has been settled. Code phase as follows:

 

 

int CVICALLBACK DrawCanvas(int panelHandle, int controlID, int event, void *callbackData, int eventData1, int eventData2)
{
    static int startAng = 0;
    static int counter = 1;
    
    
    switch (event)
    {
        case EVENT_TIMER_TICK:
            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_PEN_COLOR, MakeColor(199, 172, 223));  
            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_PEN_MODE, VAL_XOR_MODE);
            SetCtrlAttribute (radarPanel, RADARPANEL_CANVAS, ATTR_DRAW_POLICY, VAL_MARK_FOR_UPDATE);
            if (counter % 2 != 0)
            {
                CanvasDrawArc(radarPanel, RADARPANEL_CANVAS, MakeRect(0,0,height+10, width+10), startAng, 150, VAL_DRAW_FRAME_AND_INTERIOR);
                counter ++;
            }
            else
            {
                CanvasDrawArc(radarPanel, RADARPANEL_CANVAS, MakeRect(0,0,height+10, width+10), startAng, 150, VAL_DRAW_FRAME_AND_INTERIOR);
                counter --;
                Delay(0.2);
                startAng += 10;
                if (startAng == 3600)
                {
                    startAng = 0;
                }
            

            }
            break;
            
    }
    return 0;
}

 

Through add a Delay() in the else area.

0 Kudos
Message 8 of 8
(4,211 Views)