【QGraphicsItem通过四个角缩放功能】

7 篇文章 3 订阅

〇、先上效果图

在这里插入图片描述

一、QGraphicsItem自定义继承框架(如下图所示)

在这里插入图片描述

二、解释说明

  1. 代码中的 m_BlockItem 是 FlowBlockItem 类型,是成员变量;
  2. DotItem是边中点那个圆点
  3. TextItem是中间文本框

三、上代码

EnumHeader.h

#ifndef ENUMHEADER_H
#define ENUMHEADER_H

#include <QObject>
#include <QMetaEnum>

// Item的Class
#define ITEM_CLASS  Qt::UserRole+1

// Item的相同Class中的不同分别
#define ITEM_TYPE  Qt::UserRole+2

class EnumType : public QObject
{
    Q_OBJECT
public:
    // BlockItem的类别
    enum BlockItemType
    {
        // 弧边矩形
        BlockItemType_ArcRect = 1,

        // 菱形
        BlockItemType_Diamond,

        // 矩形
        BlockItemType_Rect,

        // 平行四边形
        BlockItemType_Parallelogram = 4
    };
    Q_ENUM(BlockItemType)

    // BlockItem的SquareItem的所在方位
    enum SquareItemDirection
    {
        SquareItem_LeftTop = 5,
        SquareItem_LeftBottom,
        SquareItem_RightBottom,
        SquareItem_RightTop = 8
    };
    Q_ENUM(SquareItemDirection)

    // BlockItem的DotItem的所在方位
    enum DotItemDirection
    {
        DotItem_Left = 9,
        DotItem_Bottom,
        DotItem_Right,
        DotItem_Top = 12
    };    
    Q_ENUM(DotItemDirection)

    enum LineItemDirection
    {
        LineItem_Left = 13,
        LineItem_Down,
        LineItem_Right,
        LineItem_Up = 16
    };
    Q_ENUM(LineItemDirection)

    // item的Class类
    enum ItemClass
    {
        // UserType = 65536
        ItemClass_FLowBlockItem = 65536 + 1,
        ItemClass_FLowLineItem,
        ItemClass_SquareItem,
        ItemClass_DotItem,
        ItemClass_TextItem,
        ItemClass_QGraphicsPolygonItem
    };
    Q_ENUM(ItemClass)
};

#endif // ENUMHEADER_H

// 辅助方法(缩放模块单元)
void BlockItemClass::zoomBlockItem(SquareItem *squareItem, QPointF cursorPos)
{
    // 鼠标点击的SquareItem所在的方位(枚举变量:squareItem在BlockItem四个角的方位标识)
    int squareItemDirection;

    // BlockItem的初始坐标
    QPointF oldBlockPos;

    // 缩放后模块新坐标点(因为除了通过左下角缩放,都会改变坐标,因为坐标是以左上角为基准的)
    QPointF newBlockPos;

    // 缩放时静止不动的点(举例:如果通过左下角缩放,那么右上角就是静止不动的点)
    QPointF staticPos;

    // 鼠标点cursorPos所在的角的顶点坐标(指的是BlockItem的角的坐标,注意不是cursorPos因为有一点偏移量)
    // 此版本还没开发这个偏移功能,有了这个功能在缩放时鼠标的样式就不会改变了(还有一个方案,可以尝试,就是将SquareItem设置为可选择可移动,以此来缩放)
    QPointF movePos;

    // 理论上缩放后最小的点坐标
    QPointF minPos;

    qreal blockWidth,blockHeight;

    // 限制最小缩放大小坐标数值
    qreal x,y;

    squareItemDirection = squareItem->data(ITEM_TYPE).toInt();
    oldBlockPos = m_BlockItem->scenePos();
    blockWidth = m_BlockItem->boundingRect().width();
    blockHeight = m_BlockItem->boundingRect().height();
    
    switch (squareItemDirection)
    {
        case EnumType::SquareItem_LeftTop:

            // 缩放时静止不动的点:即BlockItem右下角点坐标
            staticPos = oldBlockPos + QPointF(blockWidth,blockHeight);
            minPos = staticPos + QPointF( -100.0, -50.0);

            // 限制缩放最小大小
            x = (cursorPos.rx() >= minPos.rx() ? minPos.rx() : cursorPos.rx());
            y = (cursorPos.ry() >= minPos.ry() ? minPos.ry() : cursorPos.ry());
            movePos = QPointF(x,y);

            newBlockPos = movePos;
            blockWidth = staticPos.rx() - movePos.rx();
            blockHeight = staticPos.ry() - movePos.ry();

            break;
        case EnumType::SquareItem_LeftBottom:

            // 缩放时静止不动的点:即BlockItem右上角点坐标
            staticPos = oldBlockPos + QPointF(blockWidth,0.0);
            minPos = staticPos + QPointF(-100.0, +50);

            // 限制缩放最小大小
            x = (cursorPos.rx() >= minPos.rx() ? minPos.rx() : cursorPos.rx());
            y = (cursorPos.ry() <= minPos.ry() ? minPos.ry() : cursorPos.ry());
            movePos = QPointF(x,y);

            newBlockPos = QPointF(movePos.rx(),staticPos.ry());
            blockWidth = staticPos.rx() - movePos.rx();
            blockHeight = movePos.ry() - staticPos.ry();

            break;
        case EnumType::SquareItem_RightBottom:

            // 缩放时静止不动的点:即BlockItem左上角点坐标
            staticPos = oldBlockPos;
            minPos = staticPos + QPointF(+100.0, +50.0);

            // 限制缩放最小大小
            x = (cursorPos.rx() <= minPos.rx() ? minPos.rx() : cursorPos.rx());
            y = (cursorPos.ry() <= minPos.ry() ? minPos.ry() : cursorPos.ry());
            movePos = QPointF(x,y);

            newBlockPos = oldBlockPos;
            blockWidth = movePos.rx() - staticPos.rx() ;
            blockHeight = movePos.ry() - staticPos.ry() ;
            break;
        case EnumType::SquareItem_RightTop:

            // 缩放时静止不动的点:即BlockItem左下角点坐标
            staticPos = oldBlockPos + QPointF(0.0,blockHeight);
            minPos = staticPos + QPointF(+100.0,-50.0);

            // 限制缩放最小大小
            x = (cursorPos.rx() <= minPos.rx() ? minPos.rx() : cursorPos.rx());
            y = (cursorPos.ry() >= minPos.ry() ? minPos.ry() : cursorPos.ry());
            movePos = QPointF(x,y);

            newBlockPos = QPointF(staticPos.rx(),movePos.ry());
            blockWidth = movePos.rx() - staticPos.rx();
            blockHeight = staticPos.ry() - movePos.ry();
            break;
        default:
            break;
    }

    // 设置BlockItem新的坐标点
    m_BlockItem->setPos(newBlockPos);
    
    // 这里的setWidth()是我的自定义类(FlowBlockItem)里面的自己写的函数(见下面的代码片段)
    m_BlockItem->setWidth(blockWidth);
    m_BlockItem->setHeight(blockHeight);
	
	// 下面三个分别是都是更新缩放后的坐标
    updateSquareItem();
    updateDotItem();
    updateTextItem();

}

FlowBlockItem自定义类

void FlowBlockItem::setHeight(const qreal &Height)
{
    m_Height = Height;
}

void FlowBlockItem::setWidth(const qreal &Width)
{
    m_Width = Width;
}

// 继承重写函数(所有绘制都要被限制在这个矩形内部)
QRectF FlowBlockItem::boundingRect(void) const
{
    // 设置Item的矩形默认大小
    return QRectF(0,0,m_Width,m_Height);
}

### 回答1: QGraphicsItemQt中的一个类,用于在图形场景中绘制2D图形对象。线宽是QGraphicsItem中一个可调整的属性,用于定义绘制线条的宽度。缩放是另一个属性,用于调整绘制对象的大小。 在QGraphicsItem中,可以通过设置线宽属性来改变绘制线条的粗细。可以使用setPen方法来设置线条的颜色和宽度。例如,可以通过以下代码将线条宽度设置为2个像素: QPen pen; pen.setWidth(2); item->setPen(pen); 通过设置线宽,可以调整绘制对象的外观,以便更好地满足设计需求。 缩放是另一个重要的操作,可以通过设置QGraphicsItem缩放属性来调整绘制对象的大小。可以使用setScale方法来设置缩放因子,该因子指定了对象在水平和垂直方向上的缩放倍数。例如,可以使用以下代码将对象在水平和垂直方向上都缩放为原来的一半: item->setScale(0.5); 通过缩放功能,可以实现图形对象的放大和缩小效果,以及实现不同尺寸的图形对象的显示。 QGraphicsItem的线宽和缩放属性是灵活的,可以根据具体需求进行调整。通过设置线宽和缩放属性,我们可以实现绘制具有不同外观和大小的图形对象,以满足不同的图形设计要求。 ### 回答2: QGraphicsItem中的线宽缩放是指在对图形项进行缩放操作时,其边界线的宽度是否也会相应地进行缩放QGraphicsItemQt中用于绘制2D图形的基类,它提供了丰富的绘图功能。在进行缩放操作时,QGraphicsItem会根据其当前的缩放因子对图形进行相应的缩放,包括图形的位置、大小和旋转度等。 在默认情况下,QGraphicsItem的线宽不会随着缩放而改变,也就是说,在缩放过程中,图形项的线宽保持不变。这是为了保持图形的清晰度和边界的一致性。 然而,如果我们希望在缩放过程中同时改变线宽,我们可以通过以下步骤实现: 1. 在创建QGraphicsItem的时候,设置其属性QGraphicsItem::ItemIgnoresTransformations,这样它就会忽略缩放操作对其的影响。 2. 重写QGraphicsItem的paint()函数,在函数中根据当前的缩放因子和线宽比例绘制图形。可以通过调用pen()方法获取当前的画笔对象,并设置其线宽。 这样,在进行缩放操作时,图形项的线宽也会相应地进行缩放,保证了图形的比例和线宽的一致性。 总而言之,QGraphicsItem中的线宽缩放是可以实现的,只需要通过设置属性和重写绘制函数的方式来实现。这样可以根据实际需求来调整图形项在缩放时线宽的变化。 ### 回答3: QGraphicsItem 的线宽是指在绘制图形元素时所使用的线条的宽度。默认情况下,线宽为0,即不可见。 在QGraphicsItem 中,可以通过 setPen() 函数来设置线宽。可以传入一个 QPen 对象,通过设置其线宽属性来修改线宽的大小。例如,可以使用 setWidth() 函数来设置线宽的大小。较大的线宽将会生成更宽的线条,而较小的线宽则会生成更细的线条。 线宽的缩放可以通过 setScale() 函数来实现。该函数可以对图形元素进行缩放操作。通过设置缩放因子,可以将图形元素的大小进行相应的缩放。当缩放因子为1时,图形元素保持原始大小。当缩放因子大于1时,图形元素放大;当缩放因子小于1时,图形元素缩小。 需要注意的是,QGraphicsItem 会维护一个绘制的轮廓区域,而不是实际的几何形状。当进行缩放操作时,线宽也会相应地进行缩放。因此,线宽的缩放是相对于图形元素的轮廓区域而言的,而不是相对于实际几何形状。 总之,QGraphicsItem 的线宽可以通过设置 QPen 的宽度属性来修改,较大的线宽将会生成更宽的线条,而较小的线宽则会生成更细的线条。线宽的缩放可以通过设置缩放因子来实现,相应地缩放线宽和图形元素的大小。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘猫掸子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值