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

【Qt图形视图框架】自定义QGraphicsItem和QGraphicsView,实现鼠标(移动、缩放)及键盘事件、右键事件

自定义QGraphicsItem和QGraphicsView

      • 说明
      • 示例
        • `myitem.h`
        • `myitem.cpp`
        • `myview.h`
        • `myview.cpp`
        • 调用
          • `main.cpp`
      • 效果

说明

在使用Qt的图形视图框架实现功能时,一般会在其基础上进行自定义功能实现。
如:滚轮对场景的缩放,鼠标拖动场景中的项,以及可以在场景中进行右键操作等。

示例

myitem为自定义QGraphicsItem,实现了边框、重绘事件、鼠标悬停、按键、右键菜单等功能。

myitem.h
#ifndef MYITEM_H
#define MYITEM_H#include <QGraphicsItem>class MyItem : public QGraphicsItem
{
public:MyItem();// 边框virtual QRectF boundingRect() const override;// 重绘事件virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) override;// 设置笔刷inline void setColor(const QColor &color) {brushColor = color;}protected:// 鼠标按下函数,设置被点击的图形项得到焦点,并改变光标外观virtual void keyPressEvent(QKeyEvent *event) override;// 键盘按下函数,判断是不是向下方向键,若是是,则向下移动图形项virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;// 悬停事件函数,设置光标外观和提示virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;// 右键菜单函数,为图形项添加一个右键菜单virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;private:QColor brushColor; // 笔刷颜色
};
#endif // MYITEM_H
myitem.cpp
#include "myitem.h"
#include <QPainter>
#include <QCursor>
#include <QKeyEvent>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneContextMenuEvent>
#include <QMenu>#define WIDTH 40
#define HEIGHT 40#define POS 20MyItem::MyItem()
{brushColor = Qt::black;setFlag(QGraphicsItem::ItemIsFocusable);setFlag(QGraphicsItem::ItemIsMovable);setAcceptHoverEvents(true);}QRectF MyItem::boundingRect() const
{qreal adjust = 0.5; // 返回上下左右+0.5个像素return QRectF(-POS - adjust, -POS - adjust,WIDTH + adjust, HEIGHT + adjust);
}void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *,QWidget *)
{if (hasFocus()) {painter->setPen(QPen(QColor(255, 255, 255)));} else {painter->setPen(QPen(QColor(100, 100, 100)));}painter->setBrush(brushColor);painter->drawRect(-POS, -POS, WIDTH, HEIGHT);
}void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *e)
{setFocus();// 设置光标为手握下的形状setCursor(Qt::ClosedHandCursor);QGraphicsItem::mousePressEvent(e);
}void MyItem::keyPressEvent(QKeyEvent *event)
{if (Qt::Key_Down == event->key())moveBy(0, 10);else if(Qt::Key_Up == event->key())moveBy(0, -10);else if(Qt::Key_Left == event->key())moveBy(-10, 0);else if(Qt::Key_Right == event->key())moveBy(10, 0);else{}QGraphicsItem::keyPressEvent(event);
}void MyItem::hoverEnterEvent(QGraphicsSceneHoverEvent *)
{// 设置光标为手张开的形状setCursor(Qt::OpenHandCursor);setToolTip("click me");
}void MyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{QMenu menu;QAction *moveAction = menu.addAction("move origin");QAction *selectedAction = menu.exec(event->screenPos());if (selectedAction == moveAction) {setPos(0, 0);}
}
myview.h

myview继承QGraphicsView,重新实现了滚轮事件,可对场景进行缩放操作

#ifndef MYVIEW_H
#define MYVIEW_H#include <QObject>
#include <QGraphicsView>class MyView : public QGraphicsView
{Q_OBJECT
public:explicit MyView(QWidget *parent = 0);protected:// 滚轮事件:缩放virtual void wheelEvent(QWheelEvent *event) override;
};
#endif // MYVIEW_H
myview.cpp
#include "myview.h"#include "myview.h"
#include <QKeyEvent>MyView::MyView(QWidget *parent) :QGraphicsView(parent)
{
}void MyView::wheelEvent(QWheelEvent *event)
{if(event->delta() > 0){scale(1.1, 1.1);}else{scale(0.9, 0.9);}// 加上这个,否则在场景和图形项中就没法再接收到该事件了QGraphicsView::wheelEvent(event);
}
调用
main.cpp
#include <QApplication>#include "myitem.h"
#include "myview.h"
#include <QTime>
#include <QtMath>#include <QDebug>int main(int argc, char* argv[ ])
{QApplication app(argc, argv);qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));QGraphicsScene scene;// 设置场景尺寸,减少动态渲染scene.setSceneRect(-300, -225, 600, 450);// 创建项for (int i = 0; i < 5; ++i) {MyItem *item = new MyItem;item->setColor(QColor(qrand() % 256, qrand() % 256, qrand() % 256));item->setPos(i * 50 - 100, -50);scene.addItem(item);}// 声明视图MyView view;view.setScene(&scene);// 设置背景刷view.setBackgroundBrush(QBrush(QColor(220, 220, 220)));view.show();return app.exec();
}

效果

显示效果如下:

自定义图形视图

相关文章:

【Qt图形视图框架】自定义QGraphicsItem和QGraphicsView,实现鼠标(移动、缩放)及键盘事件、右键事件

自定义QGraphicsItem和QGraphicsView 说明示例myitem.hmyitem.cppmyview.hmyview.cpp调用main.cpp 效果 说明 在使用Qt的图形视图框架实现功能时&#xff0c;一般会在其基础上进行自定义功能实现。 如&#xff1a;滚轮对场景的缩放&#xff0c;鼠标拖动场景中的项&#xff0c;…...

C语言结构体指针学习

结构体变量存放内存中&#xff0c;也有起始地址&#xff0c;定义一个变量来存放这个地址&#xff0c;那这个变量就是结构体指针&#xff1b; typedef struct mydata{int a1;int a2;int a3; }mydata;void CJgtzzView::OnDraw(CDC* pDC) {CJgtzzDoc* pDoc GetDocument();ASSERT…...

华为云云耀云服务器L实例评测|部署在线轻量级备忘录 memos

华为云云耀云服务器L实例评测&#xff5c;部署在线轻量级备忘录 memos 一、云耀云服务器L实例介绍1.1 云服务器介绍1.2 产品优势1.3 应用场景1.4 支持镜像 二、云耀云服务器L实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 memos3.1 memos介绍3.2 Docker 环境搭建…...

详解Avast Driver Updater:电脑驱动更新工具的利器还是多余的软件?

亲爱的读者朋友们&#xff0c;你是不是经常为电脑的驱动问题而烦恼&#xff1f;如果是的话&#xff0c;你可能会对这款软件——Avast Driver Updater 电脑驱动更新工具感兴趣。但在你决定尝试之前&#xff0c;不妨先和我一起深入探讨一下它的优点、缺点以及它适用的使用场景。 …...

大数据Flink(九十五):DML:Window TopN

文章目录 DML:Window TopN DML:Window TopN Window TopN 定义(支持 Streaming):Window TopN 是一种特殊的 TopN,它的返回结果是每一个窗口内的 N 个最小值或者最大值。 应用场景...

使用OKHttpClient访问网络

使用OKHttpClient前要引入依赖&#xff1a; 在build.gradle(Moduel :app)中添加 implementation com.squareup.okhttp3:okhttp:3.14.1 implementation com.squareup.okhttp3:logging-interceptor:3.14.1 implementation com.squareup.okio:okio:1.6.0 1. GET&#xff08;同步…...

maui 开发AMD CPU踩的坑。

刚换的 amd R7735HS 笔记本&#xff0c;8核16线程&#xff0c;32GB内存。性能得实强悍 。 当需要发布iOS版本时发现&#xff0c;我没有macos &#xff0c;那就安装个vmware 吧。看了一下Apple 要求以后的发布的APP需要以xcode14.3或以后版本开发的版本&#xff0c;但xcode14.3…...

宝塔反代openai官方API接口详细教程,502 Bad Gateway问题解决

一、前言 宝塔反代openai官方API接口详细教程&#xff0c;实现国内使用ChatGPT502 Bad Gateway问题解决&#xff0c; 此方法最简单快捷&#xff0c;没有复杂步骤&#xff0c;不容易出错&#xff0c;即最简单&#xff0c;零代码、零部署的方法。 二、实现前提 一台海外VPS服务…...

【leetocde】128. 最长连续序列

给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1&#xff1a; 输入&#xff1a;nums [100,4,200,1,3,2] 输出&#xff1a;4 …...

【Vue3】动态 class 类

如果你想在 Vue.js 中动态设置元素的 class 类名&#xff0c;你可以使用以下两种主要方式&#xff1a; 绑定一个动态的 class 对象&#xff1a;你可以使用 v-bind 或简写的 : 来绑定一个包含类名的对象&#xff0c;其中类名的键是类名字符串&#xff0c;值是一个布尔值或计算属…...

【Redis】redis基本数据类型详解(String、List、Hash、Set、ZSet)

目录 RedisString(字符串)List(列表)Hash(字典)Set(集合)ZSet(有序集合) Redis Redis有5种基本的数据结构&#xff0c;分别为&#xff1a;string&#xff08;字符串&#xff09;、list&#xff08;列表&#xff09;、set&#xff08;集合&#xff09;、hash&#xff08;哈希&a…...

ubuntu源码安装aria2

github:GitHub - aria2/aria2: aria2 is a lightweight multi-protocol & multi-source, cross platform download utility operated in command-line. It supports HTTP/HTTPS, FTP, SFTP, BitTorrent and Metalink. 发行说明&#xff1a;GitHub - aria2/aria2 at releas…...

【多任务案例:猫狗脸部定位与分类】

【猫狗脸部定位与识别】 1 引言2 损失函数3 The Oxford-IIIT Pet Dataset数据集4 数据预处理4 创建模型输入5 自定义数据集加载方式6 显示一批次数据7 创建定位模型8 模型训练9 绘制损失曲线10 模型保存与预测 1 引言 猫狗脸部定位与识别分为定位和识别&#xff0c;即定位猫狗…...

.Net 锁的介绍

在.NET中,有多种锁机制可用于多线程编程,用来确保线程安全和共享资源的同步。以下是.NET中常见的锁机制: 1. **Monitor(互斥锁):** `Monitor` 是.NET中最基本的锁机制之一。它使用 `lock` 关键字实现,可以确保在同一时刻只有一个线程能够访问被锁定的代码块。`Monitor`…...

Office 2021 小型企业版商用办公软件评测:提升工作效率与协作能力的专业利器

作为一名软件评测人员&#xff0c;我将为您带来一篇关于 Office 2021 小型企业版商用办公软件的评测文章。在这篇评测中&#xff0c;我将从实用性、使用场景、优点和缺点等多个方面对该软件进行客观分析&#xff0c;在专业角度为您揭示它的真正实力和潜力。 一、实用性&#xf…...

Monkey测试

一&#xff1a;测试环境搭建 1&#xff1a;下载android-sdk_r24.4.1-windows 2&#xff1a;下载Java 3&#xff1a;配置环境变量&#xff1a;关于怎么配置环境变量&#xff08;百度一下&#xff1a;monkey环境搭建&#xff0c;&#xff09; 二&#xff1a;monkey测试&#xff1…...

wzx-jmw:NFL合理,但可能被颠覆。2023-2024

As well known by all, NFL is ... 没有免费的午餐理论 No Free Lunch Theorem_免费午餐理论-CSDN博客 However, if we......

密码技术 (5) - 数字签名

一. 前言 前面在介绍消息认证码时&#xff0c;我们知道消息认证码虽然可以确认消息的完整性&#xff0c;但是无法防止否认问题。而数字签名可以解决否认的问题&#xff0c;接下来介绍数字签名的原理。 二. 数字签名的原理 数字签名和公钥密码一样&#xff0c;也有公钥和私钥&am…...

php实战案例记录(10)单引号和双引号的用法和区别

在 PHP 中&#xff0c;单引号和双引号都被用于表示字符串。它们有一些共同之处&#xff0c;但也有一些明显的区别。 解析变量&#xff1a; 双引号允许解析变量&#xff0c;而单引号不会。在双引号中&#xff0c;你可以直接在字符串中插入变量&#xff0c;而不需要进行额外的连接…...

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石②

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石② 第十九章 驱动程序基石②19.3 异步通知19.3.1 适用场景19.3.2 使用流程19.3.3 驱动编程19.3.4 应用编程19.3.5 现场编程19.3.6 上机编程19.3.7 异步通知机制内核代码详解 19.4 阻塞与非阻塞19.4.1 应用编程19.4.2 驱动编程…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...