Qt区分鼠标按下时移动的是哪个多边形

news/2024/9/15 4:33:42 标签: qt多边形移动, qt, c++, Qt区分并移动多边形
  1. 使用不同的鼠标事件处理器:为每个多边形分配不同的事件处理器,或者在同一个处理器中使用逻辑来区分。

  2. 检查鼠标点击位置:在鼠标按下事件中,检查鼠标的位置是否在某个多边形的边上或顶点上。

  3. 使用图形的标识符:给每个多边形分配一个唯一的标识符,并在鼠标事件中使用这个标识符来识别多边形。

  4. 利用图形的属性:例如,可以使用图形的颜色、层级或其他属性作为区分依据。

    #include <QWidget>
    #include <QMouseEvent>
    #include <QPainter>
    #include <QVector>
    #include <QPointF>
    #include <QLineF>
    #include <cmath>
    
    class PolyWidget : public QWidget {
        Q_OBJECT
    
    public:
        PolyWidget(QWidget *parent = nullptr) : QWidget(parent) {
            // 初始化两个多边形
            polygon1 << QPointF(50, 50) << QPointF(150, 50) << QPointF(100, 150);
            polygon2 << QPointF(200, 100) << QPointF(300, 100) << QPointF(250, 200);
        }
    
    protected:
        void paintEvent(QPaintEvent *event) override {
            QPainter painter(this);
            painter.setPen(QPen(Qt::black, 2));
            
            // 绘制第一个多边形
            drawPolygon(painter, polygon1, 1);
            // 绘制第二个多边形
            drawPolygon(painter, polygon2, 2);
        }
    
        void mousePressEvent(QMouseEvent *event) override {
            if (event->button() == Qt::LeftButton) {
                if (isInsidePolygon(polygon1, event->pos())) {
                    selectedPolygon = 1;
                } else if (isInsidePolygon(polygon2, event->pos())) {
                    selectedPolygon = 2;
                }
            }
        }
    
        void mouseMoveEvent(QMouseEvent *event) override {
            if (selectedPolygon == 1 && event->buttons() & Qt::LeftButton) {
                movePolygon(polygon1, event->pos());
            } else if (selectedPolygon == 2 && event->buttons() & Qt::LeftButton) {
                movePolygon(polygon2, event->pos());
            }
            update();
        }
    
        void mouseReleaseEvent(QMouseEvent *event) override {
            selectedPolygon = 0; // 重置选中的多边形
        }
    
    private:
        QVector<QPointF> polygon1;
        QVector<QPointF> polygon2;
        int selectedPolygon = 0; // 0 表示没有多边形被选中
    
        void drawPolygon(QPainter &painter, const QVector<QPointF> &polygon, int id) {
            for (int i = 0; i < polygon.size() - 1; ++i) {
                painter.drawLine(polygon[i], polygon[i + 1]);
            }
            painter.drawLine(polygon.last(), polygon.first()); // 闭合多边形
            // 可以在这里添加更多与 id 相关的绘制逻辑
        }
    
        bool isInsidePolygon(const QVector<QPointF> &polygon, const QPointF &pos) {
            // 这里实现检测点是否在多边形内部的逻辑
            // 可以使用射线法或多边形的边界框来优化检测
            // 以下代码仅为示例,实际检测逻辑可能更复杂
            for (int i = 0; i < polygon.size() - 1; ++i) {
                QLineF line(polygon[i], polygon[i + 1]);
                if (line.intersects(QLineF(pos, pos + QPointF(1, 0)))) {
                    return true;
                }
            }
            return false;
        }
    
        void movePolygon(QVector<QPointF> &polygon, const QPointF &newPos) {
            if (selectedPolygon) {
                QPointF delta = newPos - polygon.first();
                for (QPointF &point : polygon) {
                    point += delta;
                }
            }
        }
    };
    
    #include "PolyWidget.moc" // 确保包含moc文件

    在这个示例中,PolyWidget类包含两个多边形polygon1polygon2。我们重写了paintEvent来绘制这两个多边形,并重写了鼠标事件来处理拖动逻辑。

  5. mousePressEvent:当鼠标按下时,使用isInsidePolygon函数检查鼠标点击是否在任一个多边形的边上或顶点上,根据检测结果设置selectedPolygon
  6. mouseMoveEvent:当鼠标移动时,如果左键保持按下状态,并且selectedPolygon不为0,则调用movePolygon函数移动当前选中的多边形。
  7. mouseReleaseEvent:当鼠标左键释放时,重置selectedPolygon

http://www.niftyadmin.cn/n/5561641.html

相关文章

vxe-grid 实现配置式form搜索条件 form搜索条件框可折叠 配置式table

文章目录 效果图代码 效果图 代码 <template><div class"app-container"><vxe-grid refxGrid v-bind"gridOptions" v-if"tableHeight" :height"tableHeight"><template #billDate"{ data }"><e…

应用层——HTTP

像我们电脑和手机使用的应用软件就是在应用层写的&#xff0c;当我们的数据需要传输的时候换将数据传递到传输层。 应用层专门给用户提供应用功能&#xff0c;比如HTTP,FTP… 我们程序员写的一个个解决我们实际的问题都在应用层&#xff0c;我们今天来聊一聊HTTP。 协议 协议…

CentOS软件安装与vim使用操作

目录 CentOS软件安装 软件生态的概念 CentOS软件安装 CentOS软件卸载 CentOS查看软件包 rz和sz命令 vim多模式文本编辑器 vim 的使用 命令模式 输入模式 底线命令模式 vim 按键说明 第一部分&#xff1a;一般模式可用的光标移动、复制粘贴、搜索替换等 光标移动 …

MySQL(5)表的查询

目录 1.表的查询 1.表的查询: 1.1创建表: 语法: create table 表名( 字段 类型 约束, 字段 类型 约束, ... 字段 类型 约束 ); 1.2 单行数据全行插入: &#x1f330; 表的字段都插入数据: insert into student values(100, 1000, 唐三藏, null); 1.3 多行数据 指定列插入:…

Linux:解决vim打开文件默认为replace模式

现象 Ubuntu打开 vim 默认为 replace 模式 原因 终端的编码设置与目标机器的编码设置不同。 解决方案 修改 vim 配置文件( /etc/vim/vimrc或者~/.vimrc)&#xff0c;添加&#xff1a; set termencodingutf-8 set fileformatsunix set encodingprcP.S. vimrc 中注释使用英…

数据库第一次作业,数据库建立,表的建立,约束

Windows中选择一种方式安装mysql8.0 新建产品库mydb6_product&#xff0c;新建4张表如下: 创建数据库&#xff1a; mysql> create database mydb6_product; 使用数据库 mysql> use mydb6_product; employees表 列1:id&#xff0c;整型&#xff0c;主键 列2:name&#x…

【快速逆向一/无过程/有源码】《大学》在线投稿系统

逆向日期&#xff1a;2024.07.18 使用工具&#xff1a;Node.js 加密工具&#xff1a;Crypto-js标准库 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要做的可联系我】 【点赞 收藏 关注 】仅供学习&#xff0c;仅供学习&#xff0c; 本文为快速逆向&#x…

【chatgpt】归一化前训练测试集拆分还是归一化后训练测试集拆分

先拆分数据集然后归一化 在进行机器学习建模时&#xff0c;应该先进行训练测试集拆分&#xff08;train-test split&#xff09;&#xff0c;然后对训练集进行归一化&#xff0c;再使用训练集的归一化参数对测试集进行归一化处理。这样可以确保归一化过程不泄露测试集的信息&a…