PDA

View Full Version : resizer view item does not work properly



paule22
22nd July 2015, 19:44
hello,

here are some code, that make it possible, that you can add a GraphicsScene item,
move and resize it on a view.
but when you try to resize it, the item jumps to location 0,0 on view.

so my question, how is it possible that follows old position?
and dont jump by each resize.

thank you


#include <QApplication>
#include <QtGui>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsItem>
#include <QGraphicsView>
#include <QGraphicsWidget>
#include <QStyleOptionGraphicsItem>

class MyResizeHandle : public QGraphicsRectItem
{
public:
MyResizeHandle(Qt::Alignment alignment, QGraphicsItem* parent = 0)
: QGraphicsRectItem(parent), align(alignment)
{
setRect(0, 0, 5, 5);
setBrush(Qt::black);
}

protected:
void mousePressEvent(QGraphicsSceneMouseEvent* event)
{
offset = event->pos();
}

void mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
QGraphicsItem* parent = parentItem();
if (parent && parent->isWidget())
{
QGraphicsWidget* parentWidget = static_cast<QGraphicsWidget*>(parent);
QRectF parentGeometry = parentWidget->geometry();

QRectF geometry = boundingRect();
geometry.moveTo(parentWidget->mapToParent(mapToParent(event->pos())) - offset);

if (align & Qt::AlignLeft)
parentGeometry.setLeft(geometry.left());
if (align & Qt::AlignRight)
parentGeometry.setRight(geometry.right());
if (align & Qt::AlignTop)
parentGeometry.setTop(geometry.top());
if (align & Qt::AlignBottom)
parentGeometry.setBottom(geometry.bottom());

parentWidget->setGeometry(parentGeometry);
}
}

private:
QPointF offset;
Qt::Alignment align;
};

class MyGraphicsWidget : public QGraphicsWidget
{
public:
MyGraphicsWidget(QGraphicsItem* parent = 0) : QGraphicsWidget(parent)
{
//setFlag(ItemIsMovable);
setFlags(QGraphicsItem::ItemIsSelectable |
QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemSendsGeometryChanges);

createHandle(Qt::AlignTop);
createHandle(Qt::AlignBottom);
createHandle(Qt::AlignLeft);
createHandle(Qt::AlignRight);

createHandle(Qt::AlignTop | Qt::AlignLeft);
createHandle(Qt::AlignTop | Qt::AlignRight);
createHandle(Qt::AlignBottom | Qt::AlignLeft);
createHandle(Qt::AlignBottom | Qt::AlignRight);
}

void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
Q_UNUSED(widget);
painter->drawRect(option->rect);
}

void setGeometry(const QRectF& rect)
{
QGraphicsWidget::setGeometry(rect);

QHashIterator<Qt::Alignment, MyResizeHandle*> it(resizeHandles);
while (it.hasNext())
{
it.next();
adjustHandle(it.key(), it.value());
}
}

private:
void createHandle(Qt::Alignment align)
{
resizeHandles[align] = new MyResizeHandle(align, this);
}

void adjustHandle(Qt::Alignment align, MyResizeHandle* handle)
{
QRectF bounds = boundingRect();
QRectF handleBounds = handle->boundingRect();

handleBounds.moveCenter(bounds.center());
if (align & Qt::AlignLeft)
handleBounds.moveLeft(bounds.left());
if (align & Qt::AlignRight)
handleBounds.moveRight(bounds.right());
if (align & Qt::AlignTop)
handleBounds.moveTop(bounds.top());
if (align & Qt::AlignBottom)
handleBounds.moveBottom(bounds.bottom());

handle->setPos(handleBounds.topLeft());
}

QHash<Qt::Alignment, MyResizeHandle*> resizeHandles;



QVariant itemChange(GraphicsItemChange change,
const QVariant &value)
{
if (change == ItemPositionChange && scene()) {
QPointF newPos = value.toPointF();
if(QApplication::mouseButtons() == Qt::LeftButton &&
qobject_cast<Scene*> (scene())){
Scene* customScene = qobject_cast<Scene*> (scene());
int gridSize = customScene->getGridSize();
qreal xV = round(newPos.x()/gridSize)*gridSize;
qreal yV = round(newPos.y()/gridSize)*gridSize;
return QPointF(xV, yV);
}
else
return newPos;
}
else
return QGraphicsItem::itemChange(change, value);
}
};