PDA

View Full Version : Wrong repainting on resize.



Douglish
28th February 2011, 20:13
Hi Everybody, I'm having a problem with repainting a scene, I don't know what I'm doing wrong, so here I am.

So, summary. I have a board witch is a QGraphicsView and then I have QGraphicsItem from pixmap, where I paint pixmap to painter in paint function of QGraphicsItem.

Back to QGraphicsView I set a new scene and add items. Pixmaps are rendered from svg creating new pixmap, passing it to painter and paint it using data from svg.

Then when I resize a window (in resizeEvent) I reposition items and set new size of board.
Result is wrong, see attachment.

Code is as follows:


kMancalaBoard::kMancalaBoard ( QSize dim = QSize(850, 475), QWidget *parent = 0 )
: QGraphicsView (parent) {
m_scene = new QGraphicsScene();
m_renderer = new kMancalaRenderer(this);

setScene ( m_scene );

setSize(dim);
addItems();
}

void kMancalaBoard::positionItems() {
qDebug("positionItems(): Positioning items");

qreal height = sceneRect().height();
qreal width = sceneRect().width();
qreal middle = height/2;

int treasury_width = GAP_TREASURY_WIDTH+BORDER;
int gaps_space = width - 2*treasury_width;
int gap_offset = (gaps_space-(6*GAP_WIDTH))/7;
int left_offset = treasury_width + gap_offset;

treasury[0]->setPos(BORDER, middle-GAP_TREASURY_HEIGHT/2);
treasury[1]->setPos(width-BORDER-GAP_TREASURY_WIDTH, middle-GAP_TREASURY_HEIGHT/2);

for(int i = 0; i != 6; i++) {
hole[i]->setPos(left_offset+(i*(GAP_WIDTH+gap_offset)), height*0.3);
hole[i+6]->setPos(left_offset+(i*(GAP_WIDTH+gap_offset)), height*0.7-GAP_HEIGHT);
}
}

void kMancalaBoard::addItems() {
qDebug("addItems(): Adding items");

QPixmap bean = m_renderer->renderPixmap("bean", QSize(GAP_WIDTH, GAP_HEIGHT));
for(int i = 0; i != 2; i++) {
treasury[i] = new kMancalaBoardGap(
m_renderer->renderPixmap("treasury", QSize(GAP_TREASURY_WIDTH, GAP_TREASURY_HEIGHT)),
bean
);
m_scene->addItem(treasury[i]);
}

for(int i =0; i != 12; i++) {
hole[i] = new kMancalaBoardGap(
m_renderer->renderPixmap("hole", QSize(GAP_WIDTH, GAP_HEIGHT)),
bean
);
m_scene->addItem(hole[i]);
}
}

kMancalaBoard::~kMancalaBoard() {
}

void kMancalaBoard::drawBackground(QPainter *painter, const QRectF &rect) {
qDebug("drawBackground(): Drawing background");
if ( m_renderer->elementExists ( QString ( "board" ) ) ) {
qDebug ("drawBackground(): -> Rendering" );
m_renderer->render(painter, QString ( "background" ), rect);
m_renderer->render(painter, QString ( "board" ), rect);
} else {
qDebug ("drawBackground(): -> No background found" );
}

QGraphicsView::drawBackground(painter, rect);
}

void kMancalaBoard::resizeEvent(QResizeEvent *event) {
qDebug("resizeEvent(): Resize event");
QSize s = size();

setSize(s);
positionItems();

qDebug("resizeEvent(): -> Scene size now %d x %d", s.width(), s.height());
}

void kMancalaBoard::setSize(QSize s) {
qDebug("setSize(): Setting size");
qDebug("setSize(): -> Setting scene to %d x %d", s.width(), s.height());
m_scene->setSceneRect(QRectF(0,0,s.width()-10,s.height()-10));

QRectF scene_rect = m_scene->sceneRect();
qDebug("setSize(): -> Scene rectangle: x: %lf, y: %lf, width: %lf, height: %lf", scene_rect.x(), scene_rect.y(), scene_rect.width(), scene_rect.height());
}


and kMancalaBoardGap (QGraphicsItem)


kMancalaBoardGap::kMancalaBoardGap(QPixmap pGap, QPixmap pBean)
: QGraphicsItem() {
pixmapBean = pBean;
pixmapGap = pGap;

beans = 0;
}

kMancalaBoardGap::~kMancalaBoardGap() {
}

QRectF kMancalaBoardGap::boundingRect() const {
return QRectF(0, 0, pixmapGap.width(), pixmapGap.height());
}

void kMancalaBoardGap::paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
QWidget* widget) {

qDebug("kMancalaBoardGap::paint(): Painting gap");
//painter->fillRect(0,0,pixmapGap.width(), pixmapGap.height(), Qt::transparent);
painter->drawPixmap(0,0,pixmapGap);
}

high_flyer
1st March 2011, 11:00
Result is wrong, see attachment.
Please define "wrong".
As you didn't say what is 'right'.

Douglish
1st March 2011, 23:06
I think that on the attached image is obvious what is wrong. The background of gaps is moved and not filled correctly.

high_flyer
2nd March 2011, 09:11
I think that on the attached image is obvious what is wrong.
Apparently it was not obvious, otherwise I would not have asked.

Can you show the code for m_renderer->renderPixmap()?

Douglish
2nd March 2011, 11:36
Sure, it's as follows



QPixmap kMancalaRenderer::renderPixmap(QString name, const QSize size) {
QPixmap p(size);
p.fill(Qt::transparent);

QPainter painter(&p);

if ( !elementExists(name)) {
qErrnoWarning("Element doesn't exist");
return QPixmap();
}

render(&painter, name, QRectF(0,0,size.width(), size.height()));
painter.end();

return p;
}

high_flyer
2nd March 2011, 14:14
Well, you need to resize the loaded image to fit in the new sized QPixmap!

Douglish
2nd March 2011, 15:12
But the size of a pixmap doesn't change. I'll create a pixmap of some size, then make it transparent and render a svg object over it. And after that pixmap size doesn't change, it's still the same.

high_flyer
2nd March 2011, 15:24
But if the scene is larger after the resize, then you get holes if your pixmaps wont be able to fill the larger areas they need to fill which is what you get, if I unerstand your screenshort correctly.
Can you post the "before" screen shot as well?
And what happens when you resize to a smaller size?

Why don't you just set your items on a larger item serving as background?

Douglish
2nd March 2011, 19:54
If I resize if only by 10 px result is what you can see on the first screenshot.

About the suggestion, do you mean to have the background as another item in back of all the others? Not to paint it to background?

high_flyer
3rd March 2011, 10:53
Does your background have holes in it?
Just use one without holes.

Douglish
5th March 2011, 19:02
No, it doesn't. The holes are pixmaps added to scene.