[Qt-interest] QWidget update() not triggering paintEvent()

YoBro yobro at rediffmail.com
Sun Apr 17 05:52:20 CEST 2011


Hi all!


     I realize others
 have had this problem too; but I haven't found a fix to mine yet. I was
 playing around with some code from the Qt tutorial and I am stuck 
because one of my QWidget inherited classes calls update(const QRegion&) 
but it does not trigger a call to paintEvent(..) - essentially I am 
trying to do a simple refactoring of the tutorial source code to add 
multiple shots using a CannonShot class in the 12th chapter of the Qt 
tutorial (see the link: http://doc.trolltech.com/4.3/tutorial-t12.html). 



    The CannonField update() still works correctly and causes its 
paintEvent re-implementation to be called. Its only CannonShot's 
update() that does not call its own paintEvent. (I've confirmed that it 
does get before and after the update call). Here are some snippets:

class CannonShot : public QWidget
{
   Q_OBJECT
public:
   CannonShot(QWidget *parent = 0);
   int angle() const { return shotAngle; }
   int force() const { return shotForce; }
   void shoot();
private slots:
   void moveShot();
   void plotShot();

signals:
   void hit();
   void missed();
   void angleChanged(int);
   void forceChanged(int);
...
...
private:
   paintEvent(QPaintEvent*);
   int shotTimerCount;
   QTimer* autoShotTimer;
   float shotAngle;
   float shotForce;
};


Here's a snippet of the constructor of CannonShot and where its update() is called:

CannonShot::CannonShot(QWidget *parent): QWidget(parent)
{
   shotTimerCount = 0;
   autoShotTimer = new QTimer(this);
   connect(autoShotTimer, SIGNAL(timeout()), this, SLOT(moveShot()));
}

void CannonShot::shoot()
{
   if (autoShotTimer->isActive())
   return;
   shotTimerCount = 0;
   shotAngle = CannonField::angle();
   shotForce = CannonField::force();
   autoShotTimer->start(5);
}

void CannonShot::moveShot()
{
   QRegion region = shotRect();
   ++shotTimerCount;

   QRect shotR = shotRect();
   if (shotR.x() > width() || shotR.y() > height()) {
      autoShotTimer->stop();
      emit missed();
   }
   else {
      region = region.unite(shotR);
   }
   update(region); //-Checked that code reaches before and after this call!
}

void CannonShot::paintEvent(QPaintEvent*)
{
   //-Never gets here!!
   QPainter painter(this);
   QColor color;
   //-Do whatever
}


Here is also a brief snippet of CannonField that contains the shots and calls shoot() to fire them.

class CannonField : public QWidget
{
   Q_OBJECT

public:
   CannonField(QWidget *parent = 0);
   ~CannonField();
   static int angle() { return currentAngle; }
   static int force() { return currentForce; }

public slots:
   void setAngle(int angle);
   void setForce(int force);
   void shoot();

signals:
   void hit();
   void missed();
...
...

protected:
   void paintEvent(QPaintEvent *event);

public:
   static int currentAngle;
   static int currentForce;

private:
   QVector<CannonShot*> shots;
};


And here is a snippet of CannonField's source where the shots are fired.

void CannonField::shoot()
{
   //-Added this argument since I though after searching that CannonShot 
   // needs to have a QWidget with some dimensions..
   shots.push_back(new CannonShot(this));
   (shots.back())->shoot();
}


Finally the driver looks as:

class MyWidget : public QWidget {
public:
   MyWidget(QWidget *parent = 0);
};

MyWidget::MyWidget(QWidget *parent): QWidget(parent)
{
   QPushButton *quit = new QPushButton(tr("&Quit"));
   quit->setFont(QFont("Times", 18, QFont::Bold));
   connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
   LCDRange *angle = new LCDRange(tr("&ANGLE"));
   angle->setRange(0, 90);
   LCDRange *force = new LCDRange(tr("&FORCE"));
   force->setRange(10, 50);
   CannonField *cannonField = new CannonField(this);
   connect(angle, SIGNAL(valueChanged(int)),
          cannonField, SLOT(setAngle(int)));
   connect(cannonField, SIGNAL(angleChanged(int)),
          angle, SLOT(setValue(int)));
   connect(force, SIGNAL(valueChanged(int)),
          cannonField, SLOT(setForce(int)));
   connect(cannonField, SIGNAL(forceChanged(int)),
          force, SLOT(setValue(int)));
   QPushButton *shoot = new QPushButton(tr("&Shoot"));
   shoot->setFont(QFont("Times", 18, QFont::Bold));
   connect(shoot, SIGNAL(clicked()), cannonField, SLOT(shoot()));      
   ...
   ...
   //-Other layout stuff
}

int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   MyWidget widget;
   widget.setMinimumSize(300, 300);
   widget.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
   widget.setGeometry(100, 100, 500, 355);
   widget.show();
   return app.exec();
}


Thanks again for the patience to read and respond.. any ideas as to 
what I am doing wrong and how to fix this problem are very much 
appreciated as always.
--T.
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20110417/db73e643/attachment.html 


More information about the Qt-interest-old mailing list