PDA

View Full Version : Newbie-Question: update does not trigger paintEvent



janitor
2nd June 2009, 22:48
Hello there,

I'm new to Qt and just working my way through the tutorials and docs. But now I am stuck on a seemingly simple problem. I hope that you can help me out.

So I was trying to hack one of Qt's tutorials a bit: http://doc.trolltech.com/4.3/tutorial-t10.html
I created a custom widget like this

#include "forceindicator.h"

CannonField::CannonField(QWidget *parent)
: QWidget(parent)
{
/* stuff */

indicator = new ForceIndicator;
overlayLayout = new QGridLayout(this);
overlayLayout->addWidget(indicator,0,1,Qt::AlignRight | Qt::AlignTop);
this->setLayout(overlayLayout);
/* more stuff */
}

Now this child widget "indicator" has a slot "setForce" which is triggered by some events. Within this slot (see below) update() is called.
I was thinking that this in turn would trigger a paint event and call my paintEvent(QPaintEvent *) method. However this is not working. The slot is called alright and everything before and after my update() calls is executed (checked with some couts), but the paintEvent (again couts) is not called.

I tried repaint instead - same result. Triggering the paintEvent explicitely does call my custom function.

So, what stupid mistake am I missing out on?

Thanks for your help!

Here is the header of my custom widget

#ifndef FORCEINDICATOR_H
#define FORCEINDICATOR_H

#include <QWidget>

class ForceIndicator : public QWidget
{
Q_OBJECT

public:
ForceIndicator(QWidget *parent = 0);

int force() const {return currentForce;}

public slots:
void setForce(int force);

signals:
void forceChanged(int newForce);

protected:
void paintEvent(QPaintEvent *event);

private:
int currentForce;
};

#endif

And here are parts of the body
#
include <QPainter>
#include <iostream>
#include "forceindicator.h"

void ForceIndicator::setForce(int force)
{
if (currentForce == force)
return;
std::cout << "bla" << std::endl;
currentForce = force;

update();
std::cout << "blabla" << std::endl;
//emit forceChanged(currentForce);
}


void ForceIndicator::paintEvent(QPaintEvent* /*event*/)
{
std::cout << "blub" << std::endl;
QPainter painter(this);

/* stuff */

}

nish
3rd June 2009, 01:43
as said in tutorial... update() will not call the paintEvent() everytime.
but repaint() should call it.

i have not used cout<< in any of my qt programs. try this...


#include<QDebug>
#include<QTime>

void ForceIndicator::paintEvent(QPaintEvent* /*event*/)
{
//std::cout << "blub" << std::endl;
qWarning()<<"Current Time ="<<QTime::currentTime();

QPainter painter(this);

//paint the current time somewhere it is visible in your widget.
painter.drawText(50,50,QTime::currentTime().toStri ng());

/* stuff */

}

janitor
3rd June 2009, 17:04
as said in tutorial... update() will not call the paintEvent() everytime.
but repaint() should call it.


Well, as I wrote - I tried using repaint() and it doesn't change anything.
Also using qWarning() instead of cout doesn't help, the paintEvent simply isn't called.

Could it be something in the way I create the widget? It's a child of this CannonField widget (see original post)

indicator = new ForceIndicator(this);
and then added to a layout (see below). I also omitted passing this as a parent, but that doesn't affect the behavior.
The constructor right now by the way is just:

ForceIndicator::ForceIndicator(QWidget* parent)
: QWidget(parent)
{
}


Thanks for your help!

wysota
3rd June 2009, 20:13
Could you prepare a minimal compilable example reproducing the problem?

janitor
3rd June 2009, 21:48
Thanks a lot for your replies!

While boiling it down to a minimal example I actually found my mistake. I never assigned my custom child widget a geometry or a minimum size or the like. So apparently it just had size zero and that's why the paintEvent was never even called.

gab74
24th January 2013, 17:59
Post deleted wrong section...sorry