qt 创建一个可以拖拽的矩形,简单实验 方案4

1.概要

创建一个左右边线可以拖拽的矩形,要用继承QGraphicsRectItem的类实现;

当在这个矩形内部点击时,鼠标变成手型,且可以上下拖拽整个矩形;

2.代码

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QCursor>
#include <QMouseEvent>
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
#include <QVBoxLayout>
//需求key
//创建一个左右边线可以拖拽的矩形,要用继承QGraphicsRectItem的类实现,需要完整代码;当在这个矩形内部点击时,鼠标变成手型,且可以上下拖拽整个矩形,而不是边线;完整代码且在一个文件中;QGraphicsView 在一个QWidget中显示
/***
 * 需求描述:
 * 创建一个左右边线可以拖拽的矩形,要用继承QGraphicsRectItem的类实现,需要完整代码;
 * 当在这个矩形内部点击时,鼠标变成手型,且可以上下拖拽整个矩形,而不是边线;
 * 完整代码且在一个文件中;
 * QGraphicsView 在一个QWidget中显示
 */
class ResizableRectItem2 : public QGraphicsRectItem {
public:
    ResizableRectItem2() {
        setFlag(QGraphicsItem::ItemIsMovable, false);
        setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
        setRect(0, 0, 150, 100);
        setCursor(Qt::ArrowCursor);
    }

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {
        if (event->button() == Qt::LeftButton) {
            if (isNearEdge(event->pos(), LeftEdge)) {
                draggingEdge = LeftEdge;
                qDebug()<<"draggingEdge left ";
                setCursor(Qt::SplitHCursor);
            } else if (isNearEdge(event->pos(), RightEdge)) {
                draggingEdge = RightEdge;
                setCursor(Qt::SplitHCursor);
                qDebug()<<"draggingEdge right";
            } else {
                draggingItem = true;
                lastMousePos = event->pos();
                setCursor(Qt::OpenHandCursor);
                qDebug()<<"draggingItem";
            }
            update();
        }
    }

    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override {
        if (draggingEdge == LeftEdge) {
            qreal newWidth = rect().width() - (event->pos().x() - rect().left());
            setRect(QRectF(event->pos().x(), rect().y(), newWidth, rect().height()));
        } else if (draggingEdge == RightEdge) {
            qreal newWidth = event->pos().x() - rect().left();
            setRect(QRectF(rect().left(), rect().y(), newWidth, rect().height()));
        } else if (draggingItem) {
            auto dy = event->pos().y() - lastMousePos.y();
            auto newPos = pos() + QPointF(0, dy);
            setPos(newPos);
            //lastMousePos = event->pos();
        }
    }

    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override {
        if (event->button() == Qt::LeftButton) {
            draggingEdge = NoEdge;
            draggingItem = false;
            setCursor(Qt::ArrowCursor);
            update();
            qDebug()<<"mouseReleaseEvent";
        }
    }

private:
    enum Edge { NoEdge, LeftEdge, RightEdge };
    Edge draggingEdge = NoEdge;
    bool draggingItem = false;
    QPointF lastMousePos;

    bool isNearEdge(const QPointF &pos, Edge edge) const {
        QRectF edgeRect;
        switch (edge) {
        case LeftEdge:
            edgeRect = QRectF(rect().x()-10, rect().y(), 20, rect().height());
            break;
        case RightEdge:
            edgeRect = QRectF(rect().x()+rect().width() - 10, rect().y(), 20, rect().height());
            break;
        default:
            break;
        }
        return edgeRect.contains(pos);
    }
};

class GraphicsWidget : public QWidget {
public:
    GraphicsWidget(QWidget *parent = nullptr) : QWidget(parent) {
        QVBoxLayout *layout = new QVBoxLayout(this);
        QGraphicsScene *scene = new QGraphicsScene(this);
        ResizableRectItem2 *item = new ResizableRectItem2();
        scene->addItem(item);
        QGraphicsView *view = new QGraphicsView(scene);
        layout->addWidget(view);
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    GraphicsWidget widget;
    widget.resize(500, 400);

    widget.show();

    return app.exec();
}

3.运行结果

拖拽、缩放、鼠标形状2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值