PDA

View Full Version : How to flush a QPainter in Qt 4?



choucete
3rd July 2009, 05:38
Hi, I've been working with the cannon game from the Qt tutorials (http://doc.trolltech.com/4.3/tutorial-t14.html), and as a learning experience I thought I'd try to extend it's capabilities. I added a simple points system for example, but now I was working on something more than just a one liner, so I thought that I could make it display a message every time you hit the target, to achieve it I did the following to cannonField.cpp:

1.- Created a variable that is set to true when the projectile intersects with the target.


if(shotR.intersects(targetRect())) {
autoShootTimer->stop();
targetContact = true; //Added by me
emit hit();
emit canShoot(true);
}

2.- Added a new if on the paintEvent member function:


void CannonField::paintEvent(QPaintEvent * /* event */) {
QPainter painter(this);

if(gameEnded) {
painter.setPen(Qt::black);
painter.setFont(QFont("Courier", 18, QFont::Bold));
painter.drawText(rect(), Qt::AlignCenter, tr("Game Over"));
}
/* My code */
if(targetContact) {
painter.setPen(Qt::black);
painter.setFont(QFont("Courier", 20, QFont::Bold));
painter.drawText(rect(), Qt::AlignCenter, tr("Hit!"));
}
/* End of my code */
paintCannon(painter);
paintBarrier(painter);
if(isShooting())
paintShot(painter);
if(!gameEnded)
paintTarget(painter);
}

The problem with this is that with the code as it looks right now, on the first contact with the target the "Hit!" message appears on screen, but never goes away. So I started to explore possibilities and I came up with the idea of using a flush like you do with C for stdout, and found out that there was a .flush() for QPainter in Qt 3 (found this (http://doc.trolltech.com/3.3/qpainter.html) and this (http://lists.trolltech.com/qt-interest/2002-08/thread00098-0.html)), but couldn't find it for Qt 4.

With what I thought, the code would look something like this:


void CannonField::paintEvent(QPaintEvent * /* event */) {
...
if(targetContact) {
painter.setPen(Qt::black);
painter.setFont(QFont("Courier", 20, QFont::Bold));
painter.drawText(rect(), Qt::AlignCenter, tr("Hit!"));
painter.flush(); /* So the hit message is shown on screen. */
sleep(1); /* Wait a sec before removing it.*/
targetContact = false; /* Set the variable back to false, so the message disappears. */
}
...


Is there a way to achieve this? I guess there must be, I just don't know how. And actually, would that solve it?

Another alternative I thought of was to locate the text on a newly defined QRect, and afterward to call the method eraseRect(). I didn't have the time to actually try that. Could that work?

Thanks in advance

wysota
3rd July 2009, 11:18
It doesn't go away because the area doesn't need to be repainted, it has nothing to do with flushing anything. Call QWidget::update() after some period of time (i.e. using a QTimer) and paintEvent() will be called again and if the flags are modified properly, the branch responsible for drawing the message will not be called.