代码拉取完成,页面将自动刷新
#include "anchoritem.h"
#include <QDebug>
#include <QtMath>
#include <QVector3D>
AnchorItem::AnchorItem(QRectF rect, QPixmap map)
{
m_ItemPixmap = map;
m_ItemSize = QSizeF(rect.width(), rect.height());
m_CurrentScenePos = rect.topLeft();
m_ItemRatio = m_ItemSize.width() / m_ItemSize.height();
m_TopRightAngle = qAtan(m_ItemRatio);
// qDebug()<<qRadiansToDegrees(m_TopRightAngle);
m_TopLeftAngle = M_PI - m_TopRightAngle;
// qDebug()<<qRadiansToDegrees(m_TopLeftAngle);
m_BottomRightAngle = -1.0 * m_TopRightAngle;
// qDebug()<<qRadiansToDegrees(m_BottomRightAngle);
m_BottomLeftAngle = -1.0 * m_TopLeftAngle;
// qDebug()<<qRadiansToDegrees(m_BottomLeftAngle);
setFlag(QGraphicsItem::ItemIsFocusable);
setFlag(QGraphicsItem::ItemIsSelectable);
setAcceptHoverEvents(true);
InitPixmap();
ItemResize();
setPos(m_CurrentScenePos);
}
QRectF AnchorItem::boundingRect() const
{
QRectF rect = getItemRect();
if (isSelected())
{
rect.adjust(-m_Internal, -m_Internal, m_Internal, m_Internal);
rect.adjust(-m_EllipseWidth, -m_EllipseWidth, m_EllipseWidth, m_EllipseWidth);
rect.adjust(0, 0, 0, m_LineLen + m_RotateEllipseWidth);
}
return rect;
}
void AnchorItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
painter->setRenderHint(QPainter::Antialiasing, true);
painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::NoBrush);
painter->drawPixmap(getItemRect(), m_ItemPixmap, m_ItemPixmap.rect());
if (isSelected())
{
QRectF rect = getItemRect();
const qreal penWidth = 0;
// 边框区域颜色
QColor color = QColor(Qt::gray);
// 绘制四周边框虚线
painter->setPen(QPen(color, penWidth, Qt::DashLine));
painter->setBrush(Qt::NoBrush);
rect.adjust(-m_Internal, -m_Internal, m_Internal, m_Internal);
painter->drawRect(rect);
// 绘制到旋转框的虚线
const qreal roatePointStartX = rect.left() + rect.width() / 2;
const qreal roatePointStartY = rect.bottom();
const qreal roatePointEndX = rect.left() + rect.width() / 2;
const qreal roatePointEndY = rect.bottom() + m_LineLen;
painter->drawLine(QLineF(QPointF(roatePointStartX, roatePointStartY),
QPointF(roatePointEndX, roatePointEndY)));
// 绘制控制点
painter->setPen(Qt::NoPen);
//top-left
painter->drawPixmap(m_TopLeftRect, m_ScalePixmap, m_ScalePixmap.rect());
//bottom-left
painter->drawPixmap(m_BottomLeftRect, m_ScalePixmap, m_ScalePixmap.rect());
//top-right
painter->drawPixmap(m_TopRightRect, m_ScalePixmap, m_ScalePixmap.rect());
//bottom-left
painter->drawPixmap(m_BottomRightRect, m_ScalePixmap, m_ScalePixmap.rect());
// rotate
painter->drawPixmap(m_RotateRect, m_RotatePixmap, m_RotatePixmap.rect());
}
}
void AnchorItem::keyPressEvent(QKeyEvent* event)
{
QGraphicsItem::keyPressEvent(event);
}
void AnchorItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
setFocus();
if (m_CursorShape == HAND_OPEN_CURSOR)
{
m_PressScenePos = event->scenePos();
m_CursorShape = HAND_CLOSE_CURSOR;
setCursor(Qt::ClosedHandCursor);
m_Operation = ITEM_MOVE;
}
else if ((m_CursorShape == RESIZE_TOPLEFT_CURSOR) ||
(m_CursorShape == RESIZE_TOPRIGHT_CURSOR) ||
(m_CursorShape == RESIZE_BOTTOMLEFT_CURSOR) ||
(m_CursorShape == RESIZE_BOTTOMRIGHT_CURSOR))
{
m_PressItemPos = event->pos();
m_Operation = ITEM_RESIZE;
}
else if (m_CursorShape == ROTATE_CURSOR)
{
m_PressItemPos = event->pos();
m_Transform = transform();
m_Operation = ITEM_ROTATE;
setCursor(m_RotatePressCursor);
}
QGraphicsItem::mousePressEvent(event);
}
void AnchorItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
switch (m_Operation) {
case ITEM_MOVE:
{
setPos(m_CurrentScenePos + event->scenePos() - m_PressScenePos);
emit itemPos(m_CurrentScenePos + event->scenePos() - m_PressScenePos);
update();
}
break;
case ITEM_RESIZE:
{
QPointF diff = event->pos() - m_PressItemPos;
m_PressItemPos = event->pos();
qreal width, height;
// 如果diff的宽大于高,则计算宽,在根据比例计算高
if (abs(diff.x()) >= abs(diff.y()))
{
switch (m_CursorShape) {
case RESIZE_TOPLEFT_CURSOR:
{
width = m_ItemSize.width() - 2 * diff.x();
height = width / m_ItemRatio;
}
break;
case RESIZE_TOPRIGHT_CURSOR:
{
width = m_ItemSize.width() + 2 * diff.x();
height = width / m_ItemRatio;
}
break;
case RESIZE_BOTTOMLEFT_CURSOR:
{
width = m_ItemSize.width() - 2 * diff.x();
height = width / m_ItemRatio;
}
break;
case RESIZE_BOTTOMRIGHT_CURSOR:
{
width = m_ItemSize.width() + 2 * diff.x();
height = width / m_ItemRatio;
}
break;
default:
{
width = m_ItemSize.width();
height = m_ItemSize.height();
}
break;
}
}
else {
// 如果diff的高大于宽,则计算高,在根据比例计算宽
switch (m_CursorShape) {
case RESIZE_TOPLEFT_CURSOR:
{
height = m_ItemSize.height() - 2 * diff.y();
width = height * m_ItemRatio;
}
break;
case RESIZE_TOPRIGHT_CURSOR:
{
height = m_ItemSize.height() - 2 * diff.y();
width = height * m_ItemRatio;
}
break;
case RESIZE_BOTTOMLEFT_CURSOR:
{
height = m_ItemSize.height() + 2 * diff.y();
width = height * m_ItemRatio;
}
break;
case RESIZE_BOTTOMRIGHT_CURSOR:
{
height = m_ItemSize.height() + 2 * diff.y();
width = height * m_ItemRatio;
}
break;
default:
{
width = m_ItemSize.width();
height = m_ItemSize.height();
}
break;
}
}
// 限制宽度范围
if (width < 50)
{
width = 50;
height = width / m_ItemRatio;
}
else if (width > 500)
{
width = 500;
height = width / m_ItemRatio;
}
m_ItemSize = QSizeF(width, height);
ItemResize();
update();
}
break;
case ITEM_ROTATE:
{
QVector2D startVect = QVector2D(m_PressItemPos);
startVect.normalize();
QVector2D endVect = QVector2D(event->pos());
endVect.normalize();
qreal value = QVector2D::dotProduct(startVect, endVect);
if (value > 1.0)
value = 1.0;
else if (value < -1.0)
value = -1.0;
qreal angle = qRadiansToDegrees(qAcos(value));
QVector3D vect = QVector3D::crossProduct(QVector3D(startVect, 1.0), QVector3D(endVect, 1.0));
if (vect.z() < 0)
angle *= -1.0;
m_Transform.rotate(angle);
setTransform(m_Transform);
update();
}
break;
default:break;
}
QGraphicsItem::mouseMoveEvent(event);
}
void AnchorItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
clearFocus();
setCursor(Qt::ArrowCursor);
m_CursorShape = ARROR_CURSOR;
m_Operation = ITEM_NONE;
m_CurrentScenePos = pos();
QGraphicsItem::mouseReleaseEvent(event);
}
void AnchorItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
{
if (!isSelected())
{
m_CursorShape = HAND_OPEN_CURSOR;
setCursor(Qt::OpenHandCursor);
}
else {
QPointF pos = event->pos();
QRectF rect = getItemRect();
qreal angle = qAtan2(transform().m12(), transform().m11());
QMarginsF pad = QMarginsF(1, 1, 1, 1);
rect.adjust(-m_Internal, -m_Internal, m_Internal, m_Internal);
if ((m_TopLeftRect + pad).contains(pos))
{
m_CursorShape = RESIZE_TOPLEFT_CURSOR;
angle = m_TopLeftAngle - angle;
setCursor(GetResizeCursorShape(angle));
setToolTip(QString("缩放"));
}
else if ((m_BottomRightRect + pad).contains(pos))
{
m_CursorShape = RESIZE_BOTTOMRIGHT_CURSOR;
angle = m_BottomRightAngle - angle;
setCursor(GetResizeCursorShape(angle));
setToolTip(QString("缩放"));
}
else if ((m_TopRightRect + pad).contains(pos))
{
m_CursorShape = RESIZE_TOPRIGHT_CURSOR;
angle = m_TopRightAngle - angle;
setCursor(GetResizeCursorShape(angle));
setToolTip(QString("缩放"));
}
else if ((m_BottomLeftRect + pad).contains(pos))
{
m_CursorShape = RESIZE_BOTTOMLEFT_CURSOR;
angle = m_BottomLeftAngle - angle;
setCursor(GetResizeCursorShape(angle));
setToolTip(QString("缩放"));
}
else if ((m_RotateRect + pad).contains(pos))
{
m_CursorShape = ROTATE_CURSOR;
setCursor(m_RotateHoverCursor);
setToolTip(QString("旋转"));
}
else {
if (rect.contains(pos))
{
m_CursorShape = HAND_OPEN_CURSOR;
setCursor(Qt::OpenHandCursor);
setToolTip(QString("移动"));
}
}
}
QGraphicsItem::hoverEnterEvent(event);
}
void AnchorItem::hoverMoveEvent(QGraphicsSceneHoverEvent* event)
{
if (!isSelected())
{
m_CursorShape = HAND_OPEN_CURSOR;
setCursor(Qt::OpenHandCursor);
}
else {
QPointF pos = event->pos();
QRectF rect = getItemRect();
qreal angle = qAtan2(transform().m12(), transform().m11());
QMarginsF pad = QMarginsF(1, 1, 1, 1);
rect.adjust(-m_Internal, -m_Internal, m_Internal, m_Internal);
if ((m_TopLeftRect + pad).contains(pos))
{
m_CursorShape = RESIZE_TOPLEFT_CURSOR;
angle = m_TopLeftAngle - angle;
// qDebug()<<qRadiansToDegrees(angle);
setCursor(GetResizeCursorShape(angle));
}
else if ((m_BottomRightRect + pad).contains(pos))
{
m_CursorShape = RESIZE_BOTTOMRIGHT_CURSOR;
angle = m_BottomRightAngle - angle;
// qDebug()<<qRadiansToDegrees(angle);
setCursor(GetResizeCursorShape(angle));
}
else if ((m_TopRightRect + pad).contains(pos))
{
m_CursorShape = RESIZE_TOPRIGHT_CURSOR;
angle = m_TopRightAngle - angle;
// qDebug()<<qRadiansToDegrees(angle);
setCursor(GetResizeCursorShape(angle));
}
else if ((m_BottomLeftRect + pad).contains(pos))
{
m_CursorShape = RESIZE_BOTTOMLEFT_CURSOR;
angle = m_BottomLeftAngle - angle;
// qDebug()<<qRadiansToDegrees(angle);
setCursor(GetResizeCursorShape(angle));
}
else if ((m_RotateRect + pad).contains(pos))
{
// qDebug()<<"rotate";
m_CursorShape = ROTATE_CURSOR;
setCursor(m_RotateHoverCursor);
}
else {
if (rect.contains(pos))
{
m_CursorShape = HAND_OPEN_CURSOR;
setCursor(Qt::OpenHandCursor);
}
}
}
QGraphicsItem::hoverMoveEvent(event);
}
void AnchorItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
{
m_CursorShape = ARROR_CURSOR;
setCursor(Qt::ArrowCursor);
QGraphicsItem::hoverLeaveEvent(event);
}
void AnchorItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
{
QGraphicsItem::contextMenuEvent(event);
}
QVariant AnchorItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value)
{
if (change == QGraphicsItem::ItemSelectedChange)
prepareGeometryChange();
return QGraphicsItem::itemChange(change, value);
}
QRectF AnchorItem::getItemRect() const
{
// 以图元的中心为原点
return QRectF(-m_ItemSize.width() / 2, -m_ItemSize.height() / 2,
m_ItemSize.width(), m_ItemSize.height());
}
void AnchorItem::InitPixmap()
{
m_ScalePixmap = QPixmap(":/icons/circle_grey.png");
m_RotatePixmap = QPixmap(":/icons/rotate.png");
m_RotateHoverCursor = QCursor(QPixmap(":/icons/rotate_hover.png").scaled(32, 32, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
m_RotatePressCursor = QCursor(QPixmap(":/icons/rotate_press.png").scaled(32, 32, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
}
void AnchorItem::ItemResize()
{
QRectF rect = getItemRect();
rect.adjust(-m_Internal, -m_Internal, m_Internal, m_Internal);
m_TopLeftRect = QRectF(rect.x() - m_EllipseWidth / 2, rect.y() - m_EllipseWidth / 2, m_EllipseWidth, m_EllipseWidth);
m_BottomLeftRect = QRectF(rect.x() - m_EllipseWidth / 2, rect.bottomLeft().y() - m_EllipseWidth / 2, m_EllipseWidth, m_EllipseWidth);
m_TopRightRect = QRectF(rect.topRight().x() - m_EllipseWidth / 2, rect.y() - m_EllipseWidth / 2, m_EllipseWidth, m_EllipseWidth);
m_BottomRightRect = QRectF(rect.bottomRight().x() - m_EllipseWidth / 2, rect.bottomRight().y() - m_EllipseWidth / 2, m_EllipseWidth, m_EllipseWidth);
m_RotateRect = QRectF(rect.left() + rect.width() / 2 - m_RotateEllipseWidth / 2, rect.bottom() + m_LineLen, m_RotateEllipseWidth, m_RotateEllipseWidth);
}
Qt::CursorShape AnchorItem::GetResizeCursorShape(qreal angle)
{
qreal sector = M_PI_4;
qreal value = angle + sector / 2;
qreal theta = fmod(value, M_PI);
if (theta < 0)
{
theta += M_PI;
}
int index = static_cast<int>(floor(theta / sector));
switch (index) {
case 0: return Qt::SizeHorCursor;
case 1: return Qt::SizeBDiagCursor;
case 2: return Qt::SizeVerCursor;
case 3: return Qt::SizeFDiagCursor;
default: return Qt::ArrowCursor;
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。