PDA

View Full Version : Refresh problem with QPaintEvent



rawfool
23rd April 2013, 08:59
Hi,

I'm using NightCharts to draw 3 piecharts on a QDialog. When I draw those three charts in paintEvent() and run the program, one of the charts is not painted fully. But when I resize the QDialog manually, the incomplete chart is now fully painted. How do I make this paint properly.


void Dialog::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
addGraphs(&painter);
}

void Dialog::addGraphs(QPainter *qp)
{
Nightcharts chart1;
chart1.setShadows(false);
chart1.setType(Nightcharts::Pie);
chart1.setLegendType(Nightcharts::Vertical);
chart1.setCords(50, 50, 80, 80);
chart1.addPiece("Item1",QColor(200,10,50),34);
chart1.addPiece("Item2",Qt::green,27);
chart1.addPiece("Item3",Qt::cyan,14);
chart1.addPiece("Item4",Qt::yellow,7);
chart1.addPiece("Item5",Qt::blue,4);
chart1.draw(qp);
// chart1.drawLegend(qp);

Nightcharts chart2;
chart2.setShadows(false);
chart2.setType(Nightcharts::Pie);
chart2.setLegendType(Nightcharts::Vertical);
chart2.setCords(300, 50, 80, 80);
chart2.addPiece("Item2",Qt::green,45);
chart2.addPiece("Item3",Qt::cyan,25);
chart2.addPiece("Item4",Qt::yellow,15);
chart2.addPiece("Item5",Qt::blue,15);
chart2.draw(qp);
// chart2.drawLegend(qp);

Nightcharts chart3;
chart3.setShadows(false);
chart3.setType(Nightcharts::Pie);
chart3.setLegendType(Nightcharts::Vertical);
chart3.setCords(550, 50, 80, 80);
chart3.addPiece("Item1",QColor(200,10,50), 25);
chart3.addPiece("Item3",Qt::cyan, 25);
chart3.addPiece("Item4",Qt::yellow, 15);
chart3.addPiece("Item5",Qt::blue, 15);
chart3.draw(qp);
// chart3.drawLegend(qp);
}

Before resizing QDialog
8981

After resizing QDialog
8982

Kindly help me. Thank you.

wysota
23rd April 2013, 09:09
Are you sure you should be recreating those charts in each and every paint event?

rawfool
23rd April 2013, 10:08
Not every paintEvent(), but I have to update those charts based on some activities.

And with NIghtCharts I'm not able to make it as a widget. Are there any other options ?
Thank you.

wysota
23rd April 2013, 11:16
I don't know how NightCharts works but it seems to me you should keep instances of "Nightcharts" as members of your class and in the paint event simply call draw() on each of them passing the painter where they should be drawn. Also make sure that each time you modify any of the charts, you call update( ) on the widget.

Santosh Reddy
23rd April 2013, 11:37
I don't know how NightCharts works but it seems to me you should keep instances of "Nightcharts" as members of your class and in the paint event simply call draw() on each of them passing the painter where they should be drawn. Also make sure that each time you modify any of the charts, you call update( ) on the widget.
@wysota, It looks like the NightCharts is designed to be created every time inside the QPaintEvent, having it as class member will not work. (meaning it is not reusable, no means to reset or clear the data in pie, so no way to write new data, only way out is create a new instance)

@rawfool
The problem you see is due to a bug in NightCharts. A member variable double Nightcharts::palpha; is not initialized in the ctor, just initializing it to 0 in the ctor of Nightcharts will fix the problem (unless there are other problems). Good Luck, and also report the bug to the author.

And reason the NightCharts is creatd every time in the QpaintEvent is creating this random behaviour, as each time the NightCharts object is created double Nightcharts::palpha; takes a random value and a undefined drawing of the pie chart happens

rawfool
23rd April 2013, 13:07
Setting palpha = 0 in ctor worked.


no means to reset or clear the data in pie, so no way to write new data, only way out is create a new instance
So, how do I write new data ?
Thank you.

Santosh Reddy
23rd April 2013, 13:17
no means to reset or clear the data in pie, so no way to write new data, only way out is create a new instance It already gives the solution

rawfool
23rd April 2013, 13:33
Ok. But I' unable to think how to create a new instance on some update activity.
Based on your answer, I created a singleshot timer in my ctor to update the graph. But i was not the way.

So, should I use QList or something like tht to create a new instance in run-time to append the new chart & delete the older one ? Kindly help me understand this. Thank you.




void Dialog::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
addGraphs(&painter, 20, 30, 50);
}

void Dialog::addGraphs(QPainter *qp, int i, int j, int k)
{
Nightcharts chart1;
chart1.setShadows(false);
chart1.setType(Nightcharts::Pie);
chart1.setLegendType(Nightcharts::Vertical);
chart1.setCords(50, 50, 80, 80);
chart1.addPiece("Item1",QColor(200,10,50), i);
chart1.addPiece("Item2",Qt::green, j);
chart1.addPiece("Item3",Qt::cyan, k);
chart1.draw(qp);
chart1.drawLegend(qp);

}

Santosh Reddy
23rd April 2013, 13:40
What you want to do?

If you want to update the chart, then give new values and update() that's all

I am afraid the question you are asking is making us move us away from Qt topic.

rawfool
23rd April 2013, 13:56
I've created a dummy updater(singleshot timer, to update after few seconds) to update to new values.
Now I don't know whr to call updateGraph() function. I've done something like this, but it's not updating the graphs.
Can you give some sample code to handle this pls.



Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
this->setMinimumSize(800, 250);
QTimer::singleShot(5000, this, SLOT(updateGraph()));
}

Dialog::~Dialog()
{
}


void Dialog::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
addGraphs(&painter, 20, 30, 50);
}

void Dialog::addGraphs(QPainter *qp, int i, int j, int k)
{
Nightcharts chart1;
chart1.setShadows(false);
chart1.setType(Nightcharts::Pie);
chart1.setLegendType(Nightcharts::Vertical);
chart1.setCords(50, 50, 80, 80);
chart1.addPiece("Item1",QColor(200,10,50), i);
chart1.addPiece("Item2",Qt::green, j);
chart1.addPiece("Item3",Qt::cyan, k);
chart1.draw(qp);
chart1.drawLegend(qp);

Nightcharts chart2;
chart2.setShadows(false);
chart2.setType(Nightcharts::Pie);
chart2.setLegendType(Nightcharts::Vertical);
chart2.setCords(300, 50, 80, 80);
chart2.addPiece("Item2",Qt::green, j);
chart2.addPiece("Item3",Qt::cyan,k);
chart2.addPiece("Item4",Qt::yellow,i);
chart2.draw(qp);
chart2.drawLegend(qp);

Nightcharts chart3;
chart3.setShadows(false);
chart3.setType(Nightcharts::Pie);
chart3.setLegendType(Nightcharts::Vertical);
chart3.setCords(550, 50, 80, 80);
chart3.addPiece("Item1",QColor(200,10,50), k);
chart3.addPiece("Item3",Qt::cyan, i);
chart3.addPiece("Item4",Qt::yellow, j);
chart3.draw(qp);
chart3.drawLegend(qp);
}

void Dialog::updateGraph()
{
qDebug("Updating after 5 seconds");
QPainter painter(this);
addGraphs(&painter, 50, 20, 30);
this->update();
}

Santosh Reddy
23rd April 2013, 14:39
You are on you own


#include <QtGui>
#include <QApplication>
#include "nightcharts.h"

class Dialog : public QDialog
{
Q_OBJECT

public:

explicit Dialog(QWidget *parent = 0)
: QDialog(parent)
, index(0)
{
this->setMinimumSize(800, 250);
startTimer(1000);
}

protected:

void paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
addGraphs(&painter, A[index], B[index], C[index]);
}

private:
static const int A[10];
static const int B[10];
static const int C[10];
int index;

void addGraphs(QPainter *qp, int i, int j, int k)
{
Nightcharts chart1;
chart1.setShadows(false);
chart1.setType(Nightcharts::Pie);
chart1.setLegendType(Nightcharts::Vertical);
chart1.setCords(50, 50, 80, 80);
chart1.addPiece("Item1", QColor(200,10,50), i);
chart1.addPiece("Item2", Qt::green, j);
chart1.addPiece("Item3", Qt::cyan, k);
chart1.draw(qp);
chart1.drawLegend(qp);

Nightcharts chart2;
chart2.setShadows(false);
chart2.setType(Nightcharts::Pie);
chart2.setLegendType(Nightcharts::Vertical);
chart2.setCords(300, 50, 80, 80);
chart2.addPiece("Item2",Qt::green, j);
chart2.addPiece("Item3",Qt::cyan,k);
chart2.addPiece("Item4",Qt::yellow,i);
chart2.draw(qp);
chart2.drawLegend(qp);

Nightcharts chart3;
chart3.setShadows(false);
chart3.setType(Nightcharts::Pie);
chart3.setLegendType(Nightcharts::Vertical);
chart3.setCords(550, 50, 80, 80);
chart3.addPiece("Item1",QColor(200,10,50), k);
chart3.addPiece("Item3",Qt::cyan, i);
chart3.addPiece("Item4",Qt::yellow, j);
chart3.draw(qp);
chart3.drawLegend(qp);
}

void timerEvent(QTimerEvent *)
{
index++;
index = index % 10;
this->update();
}

};

const int Dialog::A[] = { 10, 20, 30, 40, 50, 60, 70, 70, 50, 70 };
const int Dialog::B[] = { 20, 30, 40, 50, 40, 30, 20, 10, 20, 30 };
const int Dialog::C[] = { 70, 50, 30, 10, 10, 10, 10, 20, 30, 40 };

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

Dialog dialog;
dialog.exec();

return a.exec();
}

#include "main.moc"