PDA

View Full Version : Qt_Drwa_Issue



prashantbasvat
17th June 2015, 06:29
i am begineer in qt development, i am doing qt project in that project i have to draw ECG waves in qt.so i have developed basic qt-app for wave drawing,but i am facing issues is that after execution of app ,after some time(2-3 minutes) wave drawing getting slows.
so how to resolve this issue; so here is my code
(NOTE : I HAVE ATTACHED MY APP SOURCE ALSO)

sinewave.h


#ifndef sinewave_H
#define sinewave_H

#include <QMainWindow>
#include "multithread.h"

namespace Ui {
class sinewave;
}

class sinewave : public QMainWindow {
Q_OBJECT
public:

qreal amplitude;
qreal Ttime;
qreal X1; // X Cordinate
qreal Y1; // Y Cordinate
int sinCount;
int lbl1;


sinewave(QWidget *parent = 0);
~sinewave();

signals:
void drawCord(qreal x, qreal y);

protected:
void changeEvent(QEvent *e);
void paintEvent(QPaintEvent *);

private:
Ui::sinewave *ui;
QThread *thread;
MultiThread *multithread;
QPixmap *p;

private slots:
// void on_actionPause_activated();
//void on_actionThreadStart_activated();
// void on_actionStart_activated();
// void on_actionSTART_activated();
void display();
void on_pushButton_clicked();
};

#endif // sinewave_H

sinewave.cpp


#include "sinewave.h"
#include "ui_sinewave.h"
#include "multithread.h"
#include <QtGui>
#include <QPalette>
#include <cmath>
#include <QPainterPath>
#include <QPainter>
#include <QThread>
#include <QDebug>
#include <QTimer>

QTimer timer1;
QPainterPath path1;

volatile bool drawonce = 1;

static int i=0;
static int XStartpoint=0;
static int YStartpoint=0;
static int jCount=5;

sinewave::sinewave(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::sinewave)
{
ui->setupUi(this);
X1=XStartpoint=50;
Y1=YStartpoint=250;

amplitude = 10;
sinCount = 1;
Ttime = 5;



// repaint();

connect(&timer1, SIGNAL(timeout()), this, SLOT(display()));
connect(this, SIGNAL(drawCord(qreal,qreal)), this, SLOT(repaint()));
timer1.start(250); // Interval 0 means to refresh as fast as possible

// thread = new QThread();
// multithread = new MultiThread();

// multithread->moveToThread(thread);
//// connect(multithread, SIGNAL(valueChanged(QString)), ui->labelCount, SLOT(setText(QString)));
// connect(multithread, SIGNAL(multithreadRequested()), thread, SLOT(start()));
// connect(thread, SIGNAL(started()), multithread, SLOT(doMultiThraed()));
// connect(multithread, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection);
// // receive the emited signal
// connect(multithread, SIGNAL(value()),SLOT(display()));
}

sinewave::~sinewave()
{
// multithread->abort();
// thread->wait();
// qDebug()<<this->QObject::thread()->currentThreadId();
// delete thread;
// delete multithread;
delete ui;
}

void sinewave::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}


void sinewave::paintEvent(QPaintEvent *pEvent)
{
qreal tempx,tempy;
QWidget::paintEvent(pEvent);
QPen pen1(Qt::green, 1);
QPainter painter(this) ;

painter.setRenderHint(QPainter::SmoothPixmapTransf orm,true);
// setAutoFillBackground(false);
// setAttribute(Qt::WA_OpaquePaintEvent, true);
// setAttribute(Qt::WA_NoSystemBackground, true);


painter.setPen(pen1);
painter.drawLine(50,150,50,350);
painter.drawLine(50,250,350,250);

painter.drawText(360,250,"Time ");
painter.drawText(50,130,"Amplitude");

// //x-arrows

QPen pen2(Qt::red, 2);
painter.setPen(pen2);

painter.drawLine(XStartpoint,YStartpoint,XStartpoi nt-5,YStartpoint-5);
painter.drawLine(XStartpoint,YStartpoint,XStartpoi nt-5,YStartpoint+5);

//y-arrow
painter.drawLine(50,150,40,160);
painter.drawLine(50,150,60,160);

painter.setPen(pen1);

path1.moveTo(XStartpoint,YStartpoint);
// qreal tempAmp;

tempx = X1;
tempy = Y1;

path1.lineTo(QPointF(tempx,tempy));
painter.drawPath(path1);
}


/*
void sinewave::on_actionStart_activated()
{
// code to start multithread
multithread->abort();
thread->wait();
multithread->requestThread();
}
*/

/*
void sinewave::on_actionPause_activated()
{
// Pause mulithread
multithread->abort();
thread->wait();
}
*/


void sinewave::display()
{
qreal tempAmp;
if(X1 > 300)
{
// painter->eraseRect(50,150,250,200);
X1=XStartpoint=50;
Y1=YStartpoint=250;

QApplication::processEvents();
QApplication::processEvents();
emit drawCord(X1,Y1);
return;
}
for(int SS=0;SS<sinCount;SS++)
{
tempAmp=amplitude;

for(int a=1;a<amplitude;a++)
{
XStartpoint = X1;
YStartpoint = Y1;

X1+=Ttime/tempAmp;
tempAmp--;
Y1-=1;

QApplication::processEvents();
QApplication::processEvents();
emit drawCord(X1,Y1);
}

tempAmp=1;
for(int g=amplitude;g>0;g--)
{
XStartpoint = X1;
YStartpoint = Y1;

X1+=Ttime/tempAmp;
tempAmp++;
Y1+=1;

QApplication::processEvents();
QApplication::processEvents();
emit drawCord(X1,Y1);
}

// second

tempAmp=amplitude;

for(int a=1;a<amplitude;a++)
{
XStartpoint = X1;
YStartpoint = Y1;

X1+=Ttime/tempAmp;
tempAmp--;
Y1+=1;

QApplication::processEvents();
QApplication::processEvents();
emit drawCord(X1,Y1);
}

tempAmp=1;
for(int g=amplitude;g>0;g--)
{
XStartpoint = X1;
YStartpoint = Y1;

X1+=Ttime/tempAmp;
tempAmp++;
Y1-=1;

QApplication::processEvents();
QApplication::processEvents();
emit drawCord(X1,Y1);
}
}

}




void sinewave::on_pushButton_clicked()
{
// copy code to generate sin wave
amplitude=0.0;
Ttime=0.0;
X1=100.0;
Y1=400.0;
QString amp=ui->amplitude_le->text();
QString tym=ui->time_le->text();
amplitude=amp.toInt();
Ttime=tym.toInt();
XStartpoint=100;
YStartpoint=400;
sinCount=5;
repaint();

}

jefftee
17th June 2015, 06:41
When you post code, please use the
tags. Nobody wants to waste time looking over poorly formatted code and you are much more likely to get help if you make it easier to review your code.

wysota
17th June 2015, 06:55
Why are you calling processEvents() all the time?

prashantbasvat
17th June 2015, 07:00
to clear all pending paint events,even though i wont call processevents, wave drawing getting slow after some time

wysota
17th June 2015, 07:14
to clear all pending paint events
You don't have any pending paint events as you are using repaint() instead of update(). Don't do that.


even though i wont call processevents, wave drawing getting slow after some time
You are emitting a bunch of drawCord() signals, each of which results in repainting the whole widgets. I don't know what this is supposed to achieve. Why are you doing that? You end up repainting the widget thousands of times instead of once for each call to display().

prashantbasvat
17th June 2015, 07:38
actually i wont to display wave drawing so i am emitting signal to draw n display every line segment of wave

wysota
17th June 2015, 08:23
actually i wont to display wave drawing so i am emitting signal to draw n display every line segment of wave

So why are you surprised it draws slowly if you want it to draw slowly?

prashantbasvat
17th June 2015, 08:29
when i execute an application,at that instant drawing speed is fast as drawing continues gradually drawing speed reduces,this is actually problem u can execute that code and see difference in drawing speed gradually

wysota
17th June 2015, 10:37
when i execute an application,at that instant drawing speed is fast as drawing continues gradually drawing speed reduces,this is actually problem u can execute that code and see difference in drawing speed gradually

You have a timer set to 250ms. If it takes your application 5 seconds to draw a single pass then you can't expect the app to keep up drawing at 250ms. Adjust your timer to something greater than the amount of time it takes the application to draw a single pass and see if the problem persists.

Your approach is everything but optimal so don't be surprised that the program lags behind. You are drawing much too much than required.

prashantbasvat
17th June 2015, 10:58
after increasing timer period also drawing getting slowed after some time

wysota
17th June 2015, 11:58
after increasing timer period also drawing getting slowed after some time

How did you measure how long it takes for your application to render a single pass?

By the way, the slowdown you observe is probably that you are constantly adding elements to the path in the paint event.

To be honest, I haven't recently seen code broken so badly as yours.

d_stranz
18th June 2015, 03:23
Ah, software to monitor ECG signals. I'm remembering my Qt Prayer at the moment.

prashantbasvat
18th June 2015, 07:29
dear d_stranz's ,
do you have any expeince in any such kind of biomedical applications.so please share m urs knowledge

yeye_olive
18th June 2015, 11:36
Let me try to expand a bit on the other remarks in this thread, because I believe you are missing the main point.

QWidget::paintEvent() is called when a widget needs to redraw a whole region of its surface, and its implementation needs to reflect that. In your case, sinewave::paintEvent() must draw all chords, not just one. You need to refactor your code. You do not need sinewave::display(), sinewave::drawCord(); you do not need to call QApplication::processEvents() or QWidget::repaint().

Here is a design proposal.

Identify the parameters of your sinewave, and declare them as private members of sinewave. From a quick look at your code it seems that amplitude and Ttime are the only parameters.
In sinewave::paintEvent(), read the values of those parameters and draw the whole sinewave accordingly. You can organize the code by defining a private helper function paintChord if you like.
After you change the values of the parameters (e.g. in sinewave::on_pushButton_clicked()), just call QWidget::update() (NOT QWidget::repaint()) to let Qt know that the widget should be repainted.

By the way, sinewave::on_pushButton_clicked() suggests that sinewave contains child widgets. Shouldn't the sinewave be painted on a sibling of the button?

When everything works, and only then, consider introducing optimizations, such as ignoring the chords outside the region to repaint in sinewave::paintEvent(), but only if you identify that as a performance bottleneck.