Results 1 to 12 of 12

Thread: Draw New data, without erasing old ones

  1. #1
    Join Date
    Dec 2008
    Posts
    31
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Draw New data, without erasing old ones

    Hi,

    I am into the development of an app, which receives data from network, and draws circular regions 192.168.1.250 , which is defined by the data received.
    I need to retain the data on the widget for some time 'x' and then change color and after some delay 'y', erase it.

    I have already coded it, by retaining the old data in a buffer and redraw all the data , when a new one arrives..

    It is consuming lot of time and its not responsive when the data rate is too high..the user has to do other operations also.

    I am planning to Shift to Graphics View, (now done using QPainter)

    Can some one help me out with code snipptes?

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Draw New data, without erasing old ones

    Quote Originally Posted by linuxdev View Post
    Can some one help me out with code snipptes?
    It's more likely to get answers if you provide some code snippets yourself. Try at least something...
    J-P Nurmi

  3. #3
    Join Date
    Dec 2008
    Posts
    31
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Exclamation Re: Draw New data, without erasing old ones

    This is one function which is called inside my paintEvent.
    Qt Code:
    1. {
    2.  
    3.  
    4. if(SVL)
    5. {
    6.  
    7. [B] This is used to draw old data in different colors and delete them once age is reached[/B]
    8. if(plotdetails.isEmpty() == false)
    9. {
    10.  
    11. if(ncm_received == 1) //Data received from Tcp Socket, used to update the age
    12. {
    13. for(int i=0;i<plotdetails.size();i++)
    14. {
    15. tempplot = plotdetails.at(i);
    16. if(tempplot.age==1)
    17. {
    18. tempplot.scan = 1;
    19. }
    20. else if(tempplot.age==2)
    21. {
    22. tempplot.scan = 2;
    23. }
    24. plotdetails.replace(i,tempplot);
    25. }
    26. ncm_received = 0;
    27. }
    28. for(int i=0;i<plotdetails.size();i++)
    29. {
    30. tempplot = plotdetails.at(i);
    31.  
    32. if(ncm_received == 0)
    33. {
    34. if(tempplot.tazimuth == 0)
    35. {
    36. if(tempplot.scan == 1)
    37. {
    38. tempplot.age=2;
    39. plotdetails.replace(i,tempplot);
    40. }
    41.  
    42. else if(tempplot.scan == 2)
    43. {
    44. tempplot.age=3;
    45. plotdetails.replace(i,tempplot);
    46. //plotdetails.remove(i);
    47. }
    48. }
    49.  
    50. if((tempplot.tazimuth >= capminutes) && (tempplot.tazimuth <= (capminutes + 2731u) )
    51. ||
    52. (capminutes >= 62500))
    53. {
    54. if(tempplot.scan == 1)
    55. {
    56. tempplot.age=2;
    57. plotdetails.replace(i,tempplot);
    58. }
    59.  
    60. else if(tempplot.scan == 2)
    61. {
    62. tempplot.age=3;
    63. plotdetails.replace(i,tempplot);
    64. }
    65.  
    66. }
    67.  
    68.  
    69. }
    70.  
    71.  
    72. if(tempplot.age==1 && plotenabled == true)
    73. {
    74. painter->rotate(180 + (tempplot.tazimuth/182.047222265));
    75. painter->drawPixmap(QRectF(-(plocntpix.width()/(2)),(((1.8 *
    76. tempplot.trange)/1000)*(side-50)/(ppi_defaults.max_range*2))-(plocntpix.height()/(2)),plocntpix.width(),plocntpix.height()),plocntpix,QRectF(0,0,plocntpix.width(),plocntpix.height()));
    77. painter->rotate(-(180 + (tempplot.tazimuth/182.047222265)));
    78.  
    79. }
    80. else if(tempplot.age==2 && plotenabled == true && preplotenabled == true)
    81. {
    82. painter->rotate(180 + (tempplot.tazimuth/182.047222265));
    83. painter->drawPixmap(QRectF(-plotgraypix.width()/(2),(((1.8 *
    84. tempplot.trange)/1000)*(side-50)/(ppi_defaults.max_range*2))-(plotgraypix.height()/(2)),plotgraypix.width(),plotgraypix.height()),plotgraypix,QRectF(0,0,plotgraypix.width(),plotgraypix.height()));
    85. painter->rotate(-(180 + (tempplot.tazimuth/182.047222265)));
    86.  
    87. }
    88.  
    89. else if(tempplot.age == 3)
    90. {
    91. plotdetails.remove(i);
    92. i--;
    93. //printf("REMOVED THE ELEMENT FROM QUEUE\n");
    94. }
    95.  
    96. }
    97.  
    98. }
    99.  
    100. [B] //Start drawing the plot, after receiving from the network[/B]
    101. if(m_vplot.isEmpty() == false)
    102. {
    103. for(int i = 0; i<m_vplot.size();i++)
    104. {
    105.  
    106. templot.trange = m_vplot.at(i).range;
    107. templot.tazimuth= m_vplot.at(i).azimuth;
    108. templot.elevation= m_vplot.at(i).elevation;
    109. templot.tazimuthextn= m_vplot.at(i).azimuthextn;
    110.  
    111. azimthext = (templot.tazimuthextn/182.047222265);
    112. templot.age=1;
    113. templot.scan =0;
    114.  
    115. if(plotenabled == true)
    116. {
    117. plotminutes =((m_vplot.at(i)).azimuth)/182.047222265;
    118. temp1= 180 + plotminutes;
    119. painter->rotate(temp1);
    120. painter->drawPixmap(QRectF(-(plocntpix.width()/(2)),(((1.8 *
    121. m_vplot.at(i).range)/1000)*(side-50)/(ppi_defaults.max_range*2))-(plocntpix.height()/(2)),plocntpix.width(),plocntpix.height()),plocntpix,QRectF(0,0,plocntpix.width(),plocntpix.height()));
    122. painter->rotate(-temp1);
    123.  
    124. if(!plotdetails.contains(templot))
    125. {
    126. plotdetails.append(templot);
    127. }
    128.  
    129. painter->save();
    130.  
    131. int startAngle = 0;/*(90-15) * 16*/;
    132. int spanAngle = 0;/*30 * 16;*/
    133. float rangepixel = (((1.8 * m_vplot.at(i).range)/1000)*(side-50)/(ppi_defaults.max_range*2));
    134. rangepixel = fabs(rangepixel);
    135. QRectF rectangle(-(rangepixel), -(rangepixel), (rangepixel*2), (2*rangepixel));
    136.  
    137. painter->restore();
    138.  
    139. }
    140. }
    141. m_vplot.clear();
    142. }
    143.  
    144. }
    145. else
    146. {
    147. if(plotdetails.isEmpty() == false)
    148. plotdetails.clear();
    149.  
    150. if(m_vplot.isEmpty() == false)
    151. m_vplot.clear();
    152. }
    153. #endif
    154. }
    To copy to clipboard, switch view to plain text mode 

    Variables of importance:
    a. m_vplot: is a QVector, which has all the data received from the network, using QTcpSocket (This is cleared after its used).
    b. plotdetails : is a QVector , which acts as a buffer to hold the data to be drawn and retained on the widget.

    Flow of Code:
    The data received from Tcp is drawn immediately and also added to the buffer.
    In buffer i use variable age to maintain the age of the data, if it changes then i change the color, or delete from the buffer, so that its no longer drawn.

    Looking forward to your response.

  4. #4
    Join Date
    Dec 2008
    Posts
    31
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Draw New data, without erasing old ones

    I think i have tried at least something for someone to reply

  5. #5
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Draw New data, without erasing old ones

    Why don't you use a pixmap as a drawing buffer? Whenever new data arrives, you'd draw that on the pixmap and then you'd dump the pixmap on the screen. That way you wouldn't have to always redraw everything...
    J-P Nurmi

  6. #6
    Join Date
    Dec 2008
    Posts
    31
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Draw New data, without erasing old ones

    This seems to be a good option, but i even need to remove some of the data, once it has reached a certain time.

    i.e.
    My requirement is :

    1. I receeive the data , then i draw an Ellipse at position (100, 100) in my Pixmap.
    2. after say 3 seconds i have to change the color of an item(ellipse in this case) at the same position (100,100) to grey.
    3. and then again after 3 seconds i need to erase it.

    How can i do these things if i use a Pixmap?

    can you please help me out?

  7. #7
    Join Date
    Dec 2008
    Posts
    31
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Draw New data, without erasing old ones

    I also have a background, which is having an Image , so while trying to erase the items say at (100,100) it should not erase the background

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Draw New data, without erasing old ones

    With all those requirements I'm afraid you'll have to draw everything each time. Simply store your previous steps in a buffer, remove stale data from buffer, insert new data into the buffer and then paint everything that's in the buffer. Just like the Command pattern.

  9. #9
    Join Date
    Dec 2008
    Posts
    31
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Draw New data, without erasing old ones

    Hmm , i cant do that as its a real time application, and there should be no time delay, if i dont see the item on my screen at the right time i am dead .

    I have this idea,
    a. Will draw an ellipse (which always fits within a rect of width and height as 4) in blue color.
    b. Now when its the time to change color, i can redraw the ellipse in different color.
    c. Now its time for it to erase, then i can fill the rect (width and height as 4) at the required position with black color. (I hope this shouldnt erase my background image as its a seperate Pixmap)

    Now my concern in this case would be,
    Two ellipse may overlap ,

    so i need some sort of algorithm in Qt to detect this overlap and carefully do the changing of color or erasing of already drawn items.

    I might to be going too optimistic , is it possible? can you show me the way?

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Draw New data, without erasing old ones

    Quote Originally Posted by linuxdev View Post
    Hmm , i cant do that as its a real time application,
    Do you have a real-time OS? If not, forget about real time, focus on "fastest possible".

    and there should be no time delay, if i dont see the item on my screen at the right time i am dead .
    You will see everything at the right time unless you are drawing zillions of pieces of data at once.

    I have this idea,
    a. Will draw an ellipse (which always fits within a rect of width and height as 4) in blue color.
    b. Now when its the time to change color, i can redraw the ellipse in different color.
    c. Now its time for it to erase, then i can fill the rect (width and height as 4) at the required position with black color. (I hope this shouldnt erase my background image as its a seperate Pixmap)
    At each time you will have to redraw everything regardless of what you do. Even if you use a pixmap buffer, you will have to redraw the whole pixmap. From what I see you are always drawing a single entity (ellipse or no ellipse) so speed should not be an issue here.


    so i need some sort of algorithm in Qt to detect this overlap and carefully do the changing of color or erasing of already drawn items.
    This is more complicated that using QGraphicsView which I advise you to look at.

  11. #11
    Join Date
    Dec 2008
    Posts
    31
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Draw New data, without erasing old ones

    Quote Originally Posted by wysota View Post
    You will see everything at the right time unless you are drawing zillions of pieces of data at once.
    I am seeing them at once.
    But my app response is low,
    a. data which is in the buffer is read from a network at the same rate (500 items in 4 sec)
    b. as and when i read single data into buffer i call update() on my widget to schedule a paint.
    c. In the PaintEvent, i draw all the previous data (if any) and the current received data.


    May be this is making my UI less responsive? I need to make it as a Thread but the QTCpSocket is used in many classes to send data, as far i understand the networking stuff should be limited to one QThread. So i think its little tricky , is there any example which does implement Network read and write as QThread?



    Quote Originally Posted by wysota View Post
    From what I see you are always drawing a single entity (ellipse or no ellipse) so speed should not be an issue here.
    My drawing is in a loop running till buffer size. It needs to draw 500 items in 4 secs (worst case), every time i receive a new data i have to redraw everything from the buffer along with the new data.



    Quote Originally Posted by wysota View Post
    This is more complicated that using QGraphicsView which I advise you to look at.
    Even if i move to GraphicsView, reading from Network shouldnt be a Bottle Neck to me , should i use a Thread?

    I am slowing moving to GraphicsView, but i have already developed much of code with QPainter, and trying hard to get best out of it.

    I have attached two major files of my source
    1. circlewidget.cpp : One that handles drawing
    2. HmiGenric.cpp : This handles networking. (In this sendmsg() is called from different objects to send data) , this shouldnt be a hurdle to make this class as a Thread i guess.

    Can you help me out?
    Attached Files Attached Files
    Last edited by linuxdev; 7th January 2009 at 06:55.

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Draw New data, without erasing old ones

    Quote Originally Posted by linuxdev View Post
    b. as and when i read single data into buffer i call update() on my widget to schedule a paint.
    This is wrong. Schedule a repaint at some specified interval (like 10 or 20 times a seconds). Your eyes wouldn't notice faster redraws anyway.

    I need to make it as a Thread but the QTCpSocket is used in many classes to send data, as far i understand the networking stuff should be limited to one QThread. So i think its little tricky , is there any example which does implement Network read and write as QThread?
    Using QThread will only slow down your application as you'll need to synchronize those threads all the time.

  13. The following user says thank you to wysota for this useful post:

    linuxdev (7th January 2009)

Similar Threads

  1. Best way to display lots of data fast
    By New2QT in forum Newbie
    Replies: 4
    Last Post: 16th October 2008, 23:46
  2. Replies: 7
    Last Post: 29th August 2008, 11:24
  3. Replies: 4
    Last Post: 19th October 2007, 20:47
  4. speed of setdata - lots of items in treeview
    By Big Duck in forum Qt Programming
    Replies: 4
    Last Post: 6th July 2006, 13:53
  5. Replies: 16
    Last Post: 7th March 2006, 16:57

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.