Results 1 to 7 of 7

Thread: Draw a bar chart inisde the QScrollArea

  1. #1
    Join Date
    Jul 2006
    Location
    Taiwan
    Posts
    3
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Draw a bar chart inisde the QScrollArea

    Hi,

    I am writing a program which reads lots of data (more than 1000) and show them by drawing a bar chart. I subclassed QWidget , reimplemented paintEvent() to draw my chart and called QScrollArea::setWidget() to setup the chart into the QScrollArea. But when I dragged the scroll bar in the QScrollArea, the scrollbar and chart moved extremely slowly. How do I resolve the problem?

    Here is my source code.
    Attached Files Attached Files

  2. #2
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Draw a bar chart inisde the QScrollArea

    Quote Originally Posted by ultrasonic View Post
    I am writing a program which reads lots of data (more than 1000) and show them by drawing a bar chart. I subclassed QWidget , reimplemented paintEvent() to draw my chart and called QScrollArea::setWidget() to setup the chart into the QScrollArea. But when I dragged the scroll bar in the QScrollArea, the scrollbar and chart moved extremely slowly. How do I resolve the problem?
    AFAIK QScrollArea repaint its child each times the scrollbars' values change... A solution would be to cache your chart by drawing it into an image/pixmap and displaying this cache. Alternatively you could handle scrolling internally (in your custom widget) without relying on QScrollArea. A third solution could be to reimplement QAbstractScrollArea instead of QWidget, draw your chart and make sure a full repaint isn't done each time the scrollbars move (you might want to take inspiration from QTextEdit source code then...)
    Current Qt projects : QCodeEdit, RotiDeCode

  3. #3
    Join Date
    Jul 2006
    Location
    Taiwan
    Posts
    3
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Unhappy Re: Draw a bar chart inisde the QScrollArea

    THX fullmetalcoder.

    I made my custom class which inherits QAbstractScrollArea, and drew my chart with paintEvent(). Now the scroll bar could be easily moved, but the content (my chart) is not changed. Did I forget something that should be handled?

    Here is my code I just fixed tonight.
    Attached Files Attached Files

  4. The following user says thank you to ultrasonic for this useful post:

    vinithr (9th August 2012)

  5. #4
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Draw a bar chart inisde the QScrollArea

    Quote Originally Posted by ultrasonic View Post
    Did I forget something that should be handled?
    Certainly but I don't remember what exactly... Try having a look at other scrollable widget or use a cache image instead like this :

    cmpaction.h :
    Qt Code:
    1. #ifndef CMPACTION_H
    2. #define CMPACTION_H
    3.  
    4. #include <QImage>
    5. #include <QAbstractScrollArea>
    6.  
    7. class CmpAction : public QAbstractScrollArea
    8. {
    9. Q_OBJECT
    10.  
    11. public:
    12. CmpAction(QWidget *parent = 0);
    13. void openDir(QString dirpath);
    14.  
    15. public slots:
    16. void setText(const QString &newText) { text = newText; }
    17.  
    18. protected:
    19. virtual void paintEvent(QPaintEvent *event);
    20. virtual void resizeEvent(QResizeEvent *event);
    21.  
    22. void updateGeometries();
    23. void scrollContentsBy(int dx, int dy);
    24.  
    25. private:
    26. int ARM[10000];
    27. int BUS[10000];
    28. int DWT[10000];
    29. int TIER1[10000];
    30. int OFF_CHIP[10000];
    31. QString text;
    32. int my_width;
    33. int my_height;
    34.  
    35. void init();
    36. void updateChart();
    37.  
    38. QImage img;
    39. bool bDirty;
    40. };
    41.  
    42. #endif
    To copy to clipboard, switch view to plain text mode 

    cmpaction.cpp :
    Qt Code:
    1. #include <QtGui>
    2. #include "cmpaction.h"
    3.  
    4. CmpAction::CmpAction(QWidget *parent)
    5. bDirty(false)
    6. {
    7. setMinimumSize(800,400);
    8. my_width=100+10000;
    9. my_height=400;
    10. horizontalScrollBar()->setRange(0, my_width-800);
    11. horizontalScrollBar()->setPageStep(800);
    12. verticalScrollBar()->setRange(0, my_height-400);
    13. verticalScrollBar()->setPageStep(400);
    14.  
    15. //pix = QPixmap(viewport()->size());
    16. img = QImage(viewport()->size(), QImage::Format_ARGB32);
    17.  
    18. init();
    19. }
    20.  
    21.  
    22. void CmpAction::init()
    23. {
    24. for(int i = 0;i<10000;i++) ARM[i] = BUS[i] = DWT[i] =
    25. TIER1[i] = OFF_CHIP[i] = 0;
    26. }
    27.  
    28. void CmpAction::resizeEvent(QResizeEvent *e)
    29. {
    30. QAbstractScrollArea::resizeEvent(e);
    31.  
    32. bDirty = true;
    33.  
    34. updateGeometries();
    35. }
    36.  
    37. void CmpAction::paintEvent(QPaintEvent *e)
    38. {
    39. Q_UNUSED(e)
    40.  
    41. if ( bDirty )
    42. {
    43. updateChart();
    44. }
    45.  
    46. QPainter p(viewport());
    47. const int w = width(), h = height();
    48. const int x = horizontalScrollBar()->value(), y = verticalScrollBar()->value();
    49.  
    50. //p.drawPixmap(QRect(0, 0, w, h), pix.copy(QRect(x, y, w, h)));
    51. p.drawImage(QRect(0, 0, w, h), img.copy(QRect(x, y, w, h)));
    52. }
    53.  
    54.  
    55. void CmpAction::scrollContentsBy(int dx, int dy)
    56. {
    57. viewport()->scroll(dx,dy);
    58. }
    59.  
    60.  
    61. void CmpAction::updateGeometries()
    62. {
    63. horizontalScrollBar()->setPageStep(viewport()->width());
    64. verticalScrollBar()->setPageStep(viewport()->height());
    65. horizontalScrollBar()->setRange(0,qMax(0, my_width-viewport()->width()) );
    66. verticalScrollBar()->setRange(0, qMax(0, my_height-viewport()->height()) );
    67. }
    68.  
    69. void CmpAction::openDir(QString dirpath)
    70. {
    71.  
    72. int i=0;
    73. if(dirpath == NULL)
    74. dirpath = QFileDialog::getExistingDirectory(this,
    75. tr("Select File"),
    76. QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    77.  
    78. qDebug() << dirpath;
    79.  
    80. QString arm,bus,dwt,t1,offchip;
    81.  
    82. arm = bus = dwt = t1 = offchip = dirpath;
    83.  
    84. arm.append(QString("arm_trace"));
    85. bus.append(QString("bus_trace"));
    86. dwt.append(QString("dwt_trace"));
    87. t1.append(QString("t1_trace"));
    88. offchip.append(QString("mem_trace"));
    89.  
    90. qDebug() << arm;
    91. qDebug() << bus;
    92. qDebug() << dwt;
    93. qDebug() << t1;
    94. qDebug() << offchip;
    95.  
    96.  
    97. QFile f_arm(arm);
    98. QFile f_bus(bus);
    99. QFile f_dwt(dwt);
    100. QFile f_t1(t1);
    101. QFile f_offchip(offchip);
    102. QString line;
    103.  
    104. if(f_arm.open(QFile::ReadOnly | QFile::Text))
    105. {
    106. QTextStream stream(&f_arm);
    107. line = stream.readLine(0);
    108. i=0;
    109. while(!line.isEmpty())
    110. {
    111. if (line == "1")
    112. {
    113. ARM[i]=1;
    114. }
    115. i++;
    116. line = stream.readLine(0);
    117. }
    118. }
    119.  
    120. if(f_bus.open(QFile::ReadOnly | QFile::Text))
    121. {
    122. QTextStream stream(&f_bus);
    123. line = stream.readLine(0);
    124. i=0;
    125. while(!line.isEmpty())
    126. {
    127. if (line == "1")
    128. {
    129. BUS[i]=1;
    130. }
    131. i++;
    132. line = stream.readLine(0);
    133. }
    134. }
    135.  
    136. if(f_dwt.open(QFile::ReadOnly | QFile::Text))
    137. {
    138. QTextStream stream(&f_dwt);
    139. line = stream.readLine(0);
    140. i=0;
    141. while(!line.isEmpty())
    142. {
    143. if (line == "1")
    144. {
    145. DWT[i]=1;
    146. }
    147. i++;
    148. line = stream.readLine(0);
    149. }
    150. }
    151.  
    152. if(f_t1.open(QFile::ReadOnly | QFile::Text))
    153. {
    154. QTextStream stream(&f_t1);
    155. line = stream.readLine(0);
    156. i=0;
    157. while(!line.isEmpty())
    158. {
    159. if (line == "1")
    160. {
    161. TIER1[i]=1;
    162. }
    163. i++;
    164. line = stream.readLine(0);
    165. }
    166. }
    167.  
    168. if(f_offchip.open(QFile::ReadOnly | QFile::Text))
    169. {
    170. QTextStream stream(&f_offchip);
    171. line = stream.readLine(0);
    172. i=0;
    173. while(!line.isEmpty())
    174. {
    175. if (line == "1")
    176. {
    177. OFF_CHIP[i]=1;
    178. }
    179. i++;
    180. line = stream.readLine(0);
    181. }
    182. }
    183. f_arm.close();
    184. f_bus.close();
    185. f_dwt.close();
    186. f_t1.close();
    187. f_offchip.close();
    188.  
    189. bDirty = true;
    190. }
    191.  
    192. /*
    193. QSize CmpAction::sizeHint()
    194. {
    195.   return QSize(800,400);
    196. }*/
    197.  
    198. void CmpAction::updateChart()
    199. {
    200. qDebug("painting");
    201.  
    202. QPainter painter(&img);
    203. //QPainter painter(&pix);
    204.  
    205. int i=10000;
    206.  
    207. const int start = 100;
    208. const int act_unit_w = 1;
    209. const int act_unit_h = 10;
    210.  
    211. QFontMetrics metrics(font());
    212. QColor color;
    213.  
    214. QBrush Brush1(Qt::red,Qt::SolidPattern);
    215. QBrush Brush2(Qt::green,Qt::SolidPattern);
    216. QBrush Brush3(Qt::yellow,Qt::SolidPattern);
    217. QBrush Brush4(Qt::blue,Qt::SolidPattern);
    218. QBrush badBrush(Qt::black,Qt::SolidPattern);
    219.  
    220. for(int j=0;j<i;j++){
    221. if(ARM[j]==1)
    222. {
    223. painter.fillRect(start+j*act_unit_w,100,act_unit_w,act_unit_h,Brush1);
    224. }
    225.  
    226. if(BUS[j]==1)
    227. {
    228. painter.fillRect(start+j*act_unit_w,150,act_unit_w,act_unit_h,Brush2);
    229. }
    230. if(DWT[j]==1)
    231. {
    232. painter.fillRect(start+j*act_unit_w,200,act_unit_w,act_unit_h,Brush3);
    233. }
    234. if(TIER1[j]==1)
    235. {
    236. painter.fillRect(start+j*act_unit_w,250,act_unit_w,act_unit_h,Brush4);
    237. }
    238. if(OFF_CHIP[j]==1)
    239. {
    240. painter.fillRect(start+j*act_unit_w,300,act_unit_w,act_unit_h,badBrush);
    241. }
    242. }
    243.  
    244. painter.save();
    245. painter.setBrush(badBrush);
    246. painter.setPen(QColor(Qt::black));
    247.  
    248. for( int j=start; j< 10000+start ; j += act_unit_w*100 ){
    249. painter.drawLine(j,400,j,395);
    250. painter.drawText(j,420,QString::number(j-start,10));
    251. }
    252. painter.drawText(0,100+30,QString("ARM"));
    253. painter.drawText(0,150+30,QString("BUS"));
    254. painter.drawText(0,200+30,QString("DWT"));
    255. painter.drawText(0,250+30,QString("TIER1"));
    256. painter.drawText(0,300+30,QString("MEMORY"));
    257. painter.drawText(0,0,640,50,Qt::AlignCenter,QString("Bus Activation Graph"));
    258. painter.drawLine(start,75,start,400);
    259. painter.drawLine(start,400,10000,400);
    260.  
    261. painter.restore();
    262.  
    263. //pix.save("chart.png");
    264. img.save("chart.png");
    265. bDirty = false;
    266. }
    To copy to clipboard, switch view to plain text mode 

    P.S : It is recommended not to include the QtGui file unless you need so many classes that it become too long to write all includes because it slows down the compilation a great deal...

    P.S(2) : I've not been able to try this code with real data so you may need to fix/improve the drawing of the chart...
    Current Qt projects : QCodeEdit, RotiDeCode

  6. The following user says thank you to fullmetalcoder for this useful post:

    ultrasonic (4th March 2007)

  7. #5
    Join Date
    Jul 2006
    Location
    Taiwan
    Posts
    3
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Lightbulb Re: Draw a bar chart inisde the QScrollArea

    I just figured out another way to resolve my problem. I called QPainter::translate() to translate my painter. Now my chart can display correctly.

    Thanks fullmetalcoder again .

  8. #6
    Join Date
    Apr 2012
    Posts
    49
    Thanks
    14
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Draw a bar chart inisde the QScrollArea

    Hi,

    First of all thanks for this post. I was also trying to draw bar graph in my qt application.It helped me lot.

    I am also facing the same bug that you have written. Could you please share the solution that you have found. You told that translate function can be used.?

    Thanks in advance

    Regards.
    Vinithr

  9. #7
    Join Date
    Mar 2011
    Posts
    82
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Draw a bar chart inisde the QScrollArea

    From the looks of it, it seems like he translated the graph into a more appropiate position so now he just desn't need to scroll. Translate is just that, "move around this thing considering the coordinates system".

    Also, thread revival black magic, bro. 5 years later.

Similar Threads

  1. Replies: 2
    Last Post: 8th October 2006, 20:14

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.