qt 创建一个可以拖拽的矩形,简单实践
1.概要
需求,一个可以拖拽的矩形,鼠标接近边线点击变成可拖拽形状。
2.代码
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QMouseEvent>
#include <QGraphicsSceneMouseEvent>
#include <QLabel>
//https://blog.csdn.net/xie__jin__cheng/article/details/140438674?spm=1001.2014.3001.5501
//qt 创建一个矩形,矩形的边线可以拖拽,拖拽时这个矩形随着这个边线缩放
class ResizableRectItem : public QGraphicsRectItem {
public:ResizableRectItem(const QRectF &rect, QGraphicsItem *parent = nullptr): QGraphicsRectItem(rect, parent),dragging(false),dragStartSize(QSizeF()),dragStartPos(QPointF()) {}protected:void mousePressEvent(QGraphicsSceneMouseEvent *event) override {if (event->button() == Qt::LeftButton) {// Check if the mouse click is close to any of the rectangle's edgesQRectF rect = this->rect();QPointF pos = event->pos();QSizeF size = rect.size();const int edgeSensitivity = 5; // Pixelsif (qAbs(pos.x() - rect.x()) < edgeSensitivity) {setCursor(Qt::SizeHorCursor);// Left edgedragging = true;dragStartSize = size;dragStartPos = pos;currentEdge = LeftEdge;} else if (qAbs(pos.x() - (rect.x() + rect.width())) < edgeSensitivity) {setCursor(Qt::SizeHorCursor);// Right edgedragging = true;dragStartSize = size;dragStartPos = pos;currentEdge = RightEdge;} else if (qAbs(pos.y() - rect.y()) < edgeSensitivity) {setCursor(Qt::SizeVerCursor);// Top edgedragging = true;dragStartSize = size;dragStartPos = pos;currentEdge = TopEdge;} else if (qAbs(pos.y() - (rect.y() + rect.height())) < edgeSensitivity) {setCursor(Qt::SizeVerCursor);// Bottom edgedragging = true;dragStartSize = size;dragStartPos = pos;currentEdge = BottomEdge;}}//QGraphicsRectItem::mousePressEvent(event);}void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override {if (dragging) {QPointF pos = event->pos();QSizeF newSize = dragStartSize;switch (currentEdge) {case LeftEdge:newSize.setWidth(dragStartSize.width() - ( pos.x()-dragStartPos.x()));this->setRect(QRectF(pos.x(), this->rect().y(), newSize.width(), this->rect().height()));break;case RightEdge:newSize.setWidth(dragStartSize.width() + (pos.x() - dragStartPos.x()));this->setRect(QRectF(this->rect().x(), this->rect().y(), newSize.width(), this->rect().height()));break;case TopEdge:newSize.setHeight(dragStartSize.height() - (pos.y() - dragStartPos.y()));this->setRect(QRectF(this->rect().x(), pos.y(), this->rect().width(), newSize.height()));break;case BottomEdge:newSize.setHeight(dragStartSize.height() + (pos.y() - dragStartPos.y()));this->setRect(QRectF(this->rect().x(), this->rect().y(), this->rect().width(), newSize.height()));break;}}//QGraphicsRectItem::mouseMoveEvent(event);}void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override {dragging = false;// 鼠标不在线条上,恢复默认光标形状setCursor(Qt::ArrowCursor);QGraphicsRectItem::mouseReleaseEvent(event);}private:bool dragging;QSizeF dragStartSize;QPointF dragStartPos;enum Edge { LeftEdge, RightEdge, TopEdge, BottomEdge };Edge currentEdge;
};class MainWindow : public QGraphicsView {
public:MainWindow(QWidget *parent = nullptr) : QGraphicsView(parent) {auto *scene = new QGraphicsScene(this);this->setScene(scene);// 设定原始矩形的参数int originalX = 10;int originalY = 10;int originalWidth = 200;int originalHeight = 100;auto *rect = new ResizableRectItem(QRectF(originalX, originalY, originalWidth, originalHeight));// 计算拆分后的两个矩形的参数int spacing = 10;int rect1Width = (originalWidth - spacing) / 2;int rect2Width = originalWidth - rect1Width - spacing;// 创建两个QGraphicsRectItem对象,分别代表拆分后的矩形auto* rectItem1 = new ResizableRectItem(QRectF(originalX, originalY, rect1Width, originalHeight));auto* rectItem2 = new ResizableRectItem(QRectF(originalX + rect1Width + spacing, originalY, rect2Width, originalHeight));// 将拆分后的矩形添加到场景中scene->addItem(rectItem1);scene->addItem(rectItem2);//scene->addItem(rect);}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);MainWindow window;window.resize(400, 300);window.show();return app.exec();
}
3.运行结果