当前位置: 首页 > news >正文

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.运行结果

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 网站架构核心要素
  • [C/C++入门][字符与ASCII码]6、用代码来转换字符与它的ASCII码
  • 【游戏客户端】大话slg玩法架构(三)建筑控件
  • 线性代数|机器学习-P23梯度下降
  • Perl语言之数组
  • 动手学深度学习(1.3.3 - 1.3.4)与环境互动 强化学习
  • 2.5 计算机网络
  • 车载音视频MediaPlayer优化方案
  • SpringBoot系列:通过AOP+注解优雅实现操作日志记录
  • Kubernetes面试整理-Kubernetes如何实现水平扩展?
  • Spark核心技术架构
  • python 基础语法整理
  • 【VUE】9、VUE项目中使用VUEX完成状态管理
  • jmeter持续学习之---控制器
  • 在word中删除endnote参考文献之间的空行
  • CSS实用技巧干货
  • Debian下无root权限使用Python访问Oracle
  • httpie使用详解
  • iOS 系统授权开发
  • Java教程_软件开发基础
  • JWT究竟是什么呢?
  • Python实现BT种子转化为磁力链接【实战】
  • Shell编程
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 多线程事务回滚
  • 关于 Cirru Editor 存储格式
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 机器学习中为什么要做归一化normalization
  • 爬虫模拟登陆 SegmentFault
  • 入手阿里云新服务器的部署NODE
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 突破自己的技术思维
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • 中文输入法与React文本输入框的问题与解决方案
  • 追踪解析 FutureTask 源码
  • 说说我为什么看好Spring Cloud Alibaba
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • ​一些不规范的GTID使用场景
  • ‌前端列表展示1000条大量数据时,后端通常需要进行一定的处理。‌
  • #07【面试问题整理】嵌入式软件工程师
  • #pragma once
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (二)fiber的基本认识
  • (二刷)代码随想录第16天|104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (三)docker:Dockerfile构建容器运行jar包
  • (三)Kafka 监控之 Streams 监控(Streams Monitoring)和其他
  • (一)UDP基本编程步骤
  • (转)为C# Windows服务添加安装程序
  • ****三次握手和四次挥手