PDA

View Full Version : QGraphicsSvgItem cut in half vertically when view is scaled?



droneone
15th October 2013, 01:09
Hi all,

I'm having an issue which I can't seem to get to the bottom of. I have a an SVG image, in this case, having contents which are a rectangle that is 100x300 units (1:3 ratio). I have also drawn a grid every 100 units in my view. Whenever my view is scaled so that the scene displayed is below a certain size (700 vertical pixels), my SVG image gets cut in half vertically, even though the SVG is within the center of the scene. From this point on when scaling further out, the ratio of the SVG image stays 1:1.5 until I go above a scene display size of 700 px.

Any ideas on what's causing this, and how to resolve it? I've included some screen captures and the code for the view below.

96949695



#ifndef COMPONENTEDITOR_H
#define COMPONENTEDITOR_H

#include <QObject>
#include <QPainter>
#include <QColor>
#include <QRectF>
#include <QPainter>
#include <QImage>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsSvgItem>
#include <QWheelEvent>
#include <QDebug>
#include <qmath.h>


const QString COMP_SVG = "/Users/foobarbaz/Source/ThisApp/gui/Component/Resources/SVG/dip-pkg.svg";

class ComponentEditor : public QGraphicsView {

Q_OBJECT

Q_PROPERTY(unsigned int gridSize READ gridSize WRITE setGridSize DESIGNABLE true)
Q_PROPERTY(QColor gridColor READ gridColor WRITE setGridColor DESIGNABLE true)

public:
explicit ComponentEditor(QWidget *parent = 0);
~ComponentEditor();

unsigned int gridSize();
void setGridSize(unsigned int p_size);

QColor gridColor();
void setGridColor(QColor p_color);

public slots:

void setDrag(DragMode p_mode);
void wheelEvent(QWheelEvent *p_event);

protected:

void drawBackground(QPainter *p_painter, const QRectF &p_rect);

private:

QGraphicsScene* m_scene;
QGraphicsSvgItem* m_compSvg;
unsigned int m_grid;
QColor m_color;


};

#endif // COMPONENTEDITOR_H





#include "componenteditor.h"

ComponentEditor::ComponentEditor(QWidget *parent) : QGraphicsView(parent) {

m_scene = new QGraphicsScene();

setDragMode(QGraphicsView::ScrollHandDrag);


m_scene->setSceneRect(0, 0, 10000, 10000);

setScene(m_scene);
scale(1, 1);

m_grid = 100;
m_color = Qt::blue;


QPointF center = m_scene->sceneRect().center();

m_compSvg = new QGraphicsSvgItem(COMP_SVG);
m_compSvg->setPos(center);
m_scene->addItem(m_compSvg);
centerOn(m_compSvg);
}

ComponentEditor::~ComponentEditor() {

}


void ComponentEditor::setDrag(DragMode p_mode) {
QGraphicsView::setDragMode(p_mode);
}

void ComponentEditor::drawBackground(QPainter *p_painter, const QRectF &p_rect) {

QRectF rect = sceneRect();

// p_painter->setWorldMatrixEnabled(true);
p_painter->setPen(m_color);

qreal left = int(rect.left());
qreal top = int(rect.top());

QVarLengthArray<QLineF, 100> linesX;

for (qreal x = left; x < rect.right(); x += m_grid )
linesX.append(QLineF(x, rect.top(), x, rect.bottom()));

QVarLengthArray<QLineF, 100> linesY;

for (qreal y = top; y < rect.bottom(); y += m_grid )
linesY.append(QLineF(rect.left(), y, rect.right(), y));

p_painter->drawLines(linesX.data(), linesX.size());
p_painter->drawLines(linesY.data(), linesY.size());

}

unsigned int ComponentEditor::gridSize() {
return m_grid;
}

void ComponentEditor::setGridSize(unsigned int p_size) {
m_grid = p_size;
}

QColor ComponentEditor::gridColor() {
return m_color;
}

void ComponentEditor::setGridColor(QColor p_color) {
m_color = p_color;
}

// this is run when the user uses the mouse wheel to scale up/down
// the view
void ComponentEditor::wheelEvent(QWheelEvent *p_event) {

qreal factor = qPow(1.2, p_event->delta() / 240.0);
scale(factor, factor);

// debug: new scene size
QRect sRect(0, 0, width(), height());
QRectF realRect = mapFromScene(sRect).boundingRect();

qDebug() << "CE: Scene" << realRect.width() << realRect.height() << factor;

p_event->accept();
}



Added after 1 50 minutes:

The problem, it turns out, was that half of the rectangle in the svg image was located below the lower boundary of the SVG image (had a final height + y start position value > image height). For smaller scene resolutions, it wouldn't show content outside of the svg image boundaries, but for larger ones it would.

If you find yourself here in the future, googling for an answer: fix your svg content =)