PDA

View Full Version : Strange behaviour with QPainter



franco.amato
13th January 2010, 20:46
Hi to all, I can not update the position of a moving triangle in my paintEvent. It stay at the initial position.
This little triangle is used to simulate a time position so it must move indicating time that move when a sound is playing.

Some code:


// here I determine the current time position ( where I would place the triangle
void WaveWidget::setCurrentTimePosition()
{
uint newTimeValue = getCurrentPosInSoundCoord();

/* trasform the sound position in widget coordinate */
qreal samplesPerPixel = m_wave->getSamples() / width();
qreal x_pos = newTimeValue / samplesPerPixel;

if( x_pos == m_CurrentTimePosition )
return; //no change

// I inform that time-position is changed
emit soundPosChanged( m_CurrentTimePosition, x_pos );

/* update current position */
m_CurrentTimePosition = x_pos;
}

The code of the slot that's informed of the time changes is:

void TimeWidget::soundPosChanged( qreal currentTimePosition, qreal newTimePosition )
{
int w = width();
int h = height();

m_CurrentTimePosition = currentTimePosition;

unsigned int rectWidth = ( newTimePosition - m_CurrentTimePosition ) + 4;
//qDebug() << rectWidth;

// determine the rect to update
//m_CurrentTimePosition is the triangle central point
QRect r = QRect( m_CurrentTimePosition - 3, h/2 + 1, rectWidth, h/2 );

// update it
update(r);
// update current position
m_CurrentTimePosition = newTimePosition;
}

Now the code of the paintEvent



void TimeWidget::paintEvent( QPaintEvent* e)
{
int h = height();
int w = width();

QPainter p( this );
p.setRenderHint( QPainter::Antialiasing, true );
p.fillRect( 0, 0, w, h, Qt::lightGray );
p.setBrush(Qt::blue);

static const QPointF points[3] =
{
QPointF( m_CurrentTimePosition -2, h/2),
QPointF( m_CurrentTimePosition + 2, h/2),
QPointF( m_CurrentTimePosition, h)
};

qDebug() << "TimeWidget::paintEvent - centralPoint:" << m_CurrentTimePosition;

p.drawPolygon( points, 3 );
}

I don't know why the triangle doesn't move.
The centralPoint m_CurrentTimePosition is correctly updated as I can see it at shell.

I really don't know where my code is wrong.

I tried to add the following line:

QRect region = e->rect();

as first line in the paintEvent routine and I got the following compiiler error:


error C2027: use of undefined type 'QPaintEvent'

I'm really confused.

Best Regards

wysota
13th January 2010, 21:40
I would get rid of the slot and call update() from within the method where you change the value of your property. Calling update() with a parameter doesn't make much sense as you don't use the region in your paintEvent() anyway. As for the error - #include <QPaintEvent>

franco.amato
13th January 2010, 22:12
I would get rid of the slot and call update() from within the method where you change the value of your property. Calling update() with a parameter doesn't make much sense as you don't use the region in your paintEvent() anyway. As for the error - #include <QPaintEvent>

OK error solved,
but I changed update( r ) with update and nothing change.
I can not draw the triangle. It stay at position 0.

Maybe a bug of drawPolygon?

franco.amato
13th January 2010, 22:39
I think is a drawPolygon problem.

I tried to leave update (r) in the slot and changed

p.drawPolygon( points, 3 );

with

p.drawRect(e->rect()); only for testing and now I can see something moving in the widget so I don't know how to solve it.
And other I think is better call update (r) instead of only update() so only a little portion of widget is updated.

This sould increase speed or am I wrong?

Best

faldzip
13th January 2010, 22:46
Just guessing but what if you get rid of "static" before const QPointF points[3]?

wysota
13th January 2010, 22:53
It will magically start working ;)


@franco.amato: Please look for errors in your own code instead of blaming others.

franco.amato
13th January 2010, 22:59
Just guessing but what if you get rid of "static" before const QPointF points[3]?

Yesssssssssssssssssssssssss it solved my problem.


Best

faldzip
13th January 2010, 23:05
So my advice is to read this (http://www.cppreference.com/wiki/keywords/static) carefully

franco.amato
13th January 2010, 23:14
So my advice is to read this (http://www.cppreference.com/wiki/keywords/static) carefully

I still didn't understand why the static gave that behaviour if I update at every call the member variablke

franco.amato
13th January 2010, 23:15
It will magically start working ;)


@franco.amato: Please look for errors in your own code instead of blaming others.

Sorry what are you speaking about?

faldzip
13th January 2010, 23:38
I still didn't understand why the static gave that behaviour if I update at every call the member variablke
Here is a small example:


void foo() {
static int counter = 0;
cout << "foo has been called " << ++counter << " times\n";
}

int main() {
for( int i = 0; i < 10; ++i ) foo();
}

it will display:
foo has been called 1 times
foo has been called 2 times
foo has been called 3 times
...
foo has been called 10 times

So, as it can be easily noticed, this line:

static int counter = 0;
is called ONCE, when this line is rached for the first time. So counter variable is created once and 0 is assigned to it once. Then it remains in memory for every foo() call until the end of app execution.
So in your code point[3] was created and initialized once on the first call of paintEvent() and remained there forever (until program ends).

franco.amato
14th January 2010, 00:15
Here is a small example:


void foo() {
static int counter = 0;
cout << "foo has been called " << ++counter << " times\n";
}

int main() {
for( int i = 0; i < 10; ++i ) foo();
}

it will display:
foo has been called 1 times
foo has been called 2 times
foo has been called 3 times
...
foo has been called 10 times

So, as it can be easily noticed, this line:

static int counter = 0;
is called ONCE, when this line is rached for the first time. So counter variable is created once and 0 is assigned to it once. Then it remains in memory for every foo() call until the end of app execution.
So in your code point[3] was created and initialized once on the first call of paintEvent() and remained there forever (until program ends).

OK It's all clear.
Thank you again

wysota
14th January 2010, 05:30
Sorry what are you speaking about?

Don't you think that if drawPolygon() wasn't working someone would notice it like... a few years ago?