PDA

View Full Version : QGraphicsView doesn't repaint itself - Help!



JimDaniel
18th June 2008, 06:17
So I'm messing around with the QGraphicsView framework. I thought to make a port of the old game Kung Fu from the NES. But I'm already having difficulties.

To begin I subclassed QGraphicsView and reimplemented the drawBackground method so that I could create my own scrolling background, updated in the widgets timerEvent(), but things are not working as expected.

Everything is fine, except the fact that the window does not repaint itself until I minimize/maximize. Its a little bizarre actually. The drawBackground method is being called regularly, where in theory I should be seeing the scrolling background changes, but I see no change until I minimize/maximize.

Here is my class and main.cpp. Hopefully someone can point me in the right direction. I'm a little lost.



#include <QApplication>

#include "GraphicsSceneTest.h"
#include "GraphicsViewTest.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

GraphicsSceneTest graphics_scene;
graphics_scene.setSceneRect(0, 0, 2000, 600);

GraphicsViewTest graphics_view(&graphics_scene);
graphics_view.show();

return a.exec();
}


#ifndef GRAPHICSVIEWTEST_H
#define GRAPHICSVIEWTEST_H

#include <QtGui>

class GraphicsViewTest : public QGraphicsView
{
Q_OBJECT

public:
GraphicsViewTest(QGraphicsScene * scene, QWidget * parent = 0);
virtual ~GraphicsViewTest();

protected:
void drawBackground(QPainter * painter, const QRectF & rect);

void timerEvent(QTimerEvent * te);

void keyPressEvent(QKeyEvent * ke);
void keyReleaseEvent(QKeyEvent * ke);

private:
QPixmap m_pixmap;

QRectF m_bg_one;
QRectF m_bg_two;

bool m_move_left_pressed;
bool m_move_right_pressed;
bool m_kick_pressed;
bool m_punch_pressed;
bool m_jump_pressed;
bool m_crouch_pressed;
};

#endif // GRAPHICSVIEWTEST_H


#include <QtGui>

#include "GraphicsSceneTest.h"
#include "GraphicsViewTest.h"

GraphicsViewTest::GraphicsViewTest(QGraphicsScene * scene, QWidget * parent) : QGraphicsView(scene, parent),
m_move_left_pressed(false),
m_move_right_pressed(false),
m_kick_pressed(false),
m_punch_pressed(false),
m_jump_pressed(false),
m_crouch_pressed(false)
{
this->setFixedSize(800, 600);

this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOf f);
this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff) ;

this->setViewportUpdateMode(QGraphicsView::FullViewportU pdate);

m_pixmap.load("c:/kung_fu_bg.jpg");

m_bg_one.setRect(0, 0, m_pixmap.width(), m_pixmap.height());
m_bg_two.setRect(m_pixmap.width(), 0, m_pixmap.width(), m_pixmap.height());

this->startTimer(1000 / 30);
}

GraphicsViewTest::~GraphicsViewTest()
{
}

void GraphicsViewTest::drawBackground(QPainter * painter, const QRectF & rect)
{
painter->drawPixmap(m_bg_one, m_pixmap, QRectF(m_pixmap.rect()));
painter->drawPixmap(m_bg_two, m_pixmap, QRectF(m_pixmap.rect()));
}

void GraphicsViewTest::timerEvent(QTimerEvent * te)
{
//if button is pressed in either direction, advance scroll value
if(m_move_left_pressed && !m_move_right_pressed)
{
m_bg_one.translate(-1.0, 0.0);
m_bg_two.translate(-1.0, 0.0);
}
else if(m_move_right_pressed && !m_move_left_pressed)
{
m_bg_one.translate(1.0, 0.0);
m_bg_two.translate(1.0, 0.0);
}

this->repaint();
}

void GraphicsViewTest::keyPressEvent(QKeyEvent * ke)
{
switch(ke->key())
{
case Qt::Key_A:
m_move_left_pressed = true;
break;
case Qt::Key_D:
m_move_right_pressed = true;
break;
case Qt::Key_Alt:
m_punch_pressed = true;
break;
case Qt::Key_Control:
m_kick_pressed = true;
break;
case Qt::Key_W:
m_jump_pressed = true;
break;
case Qt::Key_S:
m_crouch_pressed = true;
break;
default:
break;
}
}

void GraphicsViewTest::keyReleaseEvent(QKeyEvent * ke)
{
switch(ke->key())
{
case Qt::Key_A:
m_move_left_pressed = false;
break;
case Qt::Key_D:
m_move_right_pressed = false;
break;
case Qt::Key_Alt:
m_punch_pressed = true;
break;
case Qt::Key_Control:
m_kick_pressed = true;
break;
case Qt::Key_W:
m_jump_pressed = false;
break;
case Qt::Key_S:
m_crouch_pressed = false;
break;
default:
break;
}
}

aamer4yu
18th June 2008, 06:26
try calling QGraphicsScene::update or QGraphicsItem::update
Hope it helps :)

JimDaniel
18th June 2008, 14:08
Yep, that's what it was, in case anyone else wonders what my problem was, I added:

this->scene()->update(this->sceneRect());

at the bottom of the timerEvent, and it worked as expected.