Qt Graphics View 绘图架构

news2024/11/27 19:38:52

Qt Graphics View 绘图架构

"QWGraphicsView.h" 头文件代码如下:

#pragma once

#include <QGraphicsView>

class QWGraphicsView : public QGraphicsView
{
	Q_OBJECT

public:
	QWGraphicsView(QWidget *parent);
	~QWGraphicsView();

protected:
	void mouseMoveEvent(QMouseEvent *event);
	void mousePressEvent(QMouseEvent *event);

signals:
	void mouseMovePoint(QPoint point);
	void mouseClicked(QPoint point);
};

mouseMoveEvent()是鼠标移动事件,代码如下:

//鼠标移动事件
void QWGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
	QPoint point = event->pos();//QGraphicsView的坐标
	emit mouseMovePoint(point); //释放信号
	QGraphicsView::mouseMoveEvent(event);
}

       在此事件响应代码里,通过事件的pos()函数获取鼠标光标在视图中的坐标point,然后作为参数发射 mouseMovePoint(point)信号。这样,若在其他地方编写槽函数与此信号关联,就可以对鼠标移动事件作出响应。

mousePressEvent()是鼠标按键按下事件,代码如下:

//鼠标左键按下事件
void QWGraphicsView::mousePressEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton)
	{
		QPoint point = event->pos();//QGraphicsView的坐标
		emit mouseClicked(point);//释放信号
	}
	QGraphicsView::mousePressEvent(event);
}

       在此事件响应代码里,首先判断是否是鼠标左键按下,然后通过事件的pos()函数获取鼠标光标在视图中的坐标point,然后作为参数发射mouseClicked(point)信号。

"sample8_4QGraphicsView.h"  头文件代码如下:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_sample8_4QGraphicsView.h"

#include    <QGraphicsScene>
#include    <QLabel>


class sample8_4QGraphicsView : public QMainWindow
{
	Q_OBJECT

public:
	sample8_4QGraphicsView(QWidget *parent = Q_NULLPTR);

private:
	Ui::sample8_4QGraphicsViewClass ui;

protected:
	void resizeEvent(QResizeEvent *event);

private:
	QGraphicsScene  *scene;

	QLabel  *labViewCord;
	QLabel  *labSceneCord;
	QLabel  *labItemCord;

	void iniGraphicsSystem(); //创建Graphics View的各项

private slots:
	void on_mouseMovePoint(QPoint point);

	void on_mouseClicked(QPoint point);

};

#include "sample8_4QGraphicsView.h"

#include  "ui_sample8_4QGraphicsView.h"
#include   <QGraphicsEllipseItem>


//解决QT中中文显示乱码问题
#pragma execution_character_set("utf-8")


sample8_4QGraphicsView::sample8_4QGraphicsView(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	labViewCord = new QLabel("View 坐标:");
	labViewCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labViewCord);

	labSceneCord = new QLabel("Scene 坐标:");
	labSceneCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labSceneCord);

	labItemCord = new QLabel("Item 坐标:");
	labItemCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labItemCord);

	ui.View->setCursor(Qt::CrossCursor);
	ui.View->setMouseTracking(true);
	ui.View->setDragMode(QGraphicsView::RubberBandDrag);

	QObject::connect(ui.View, SIGNAL(mouseMovePoint(QPoint)),
		this, SLOT(on_mouseMovePoint(QPoint)));

	QObject::connect(ui.View, SIGNAL(mouseClicked(QPoint)),
		this, SLOT(on_mouseClicked(QPoint)));

	iniGraphicsSystem();
}

鼠标移动事件响应:

//鼠标移动事件,point是 GraphicsView的坐标,物理坐标
void sample8_4QGraphicsView::on_mouseMovePoint(QPoint point)
{
	labViewCord->setText(QString::asprintf("View 坐标:%d,%d", point.x(), point.y()));
	QPointF pointScene = ui.View->mapToScene(point); //转换到Scene坐标
	labSceneCord->setText(QString::asprintf("Scene 坐标:%.0f,%.0f", pointScene.x(), pointScene.y()));
}

鼠标单击事件响应:

//鼠标单击事件
void sample8_4QGraphicsView::on_mouseClicked(QPoint point)
{
	QPointF pointScene = ui.View->mapToScene(point); //转换到Scene坐标
	QGraphicsItem  *item = NULL;
	item = scene->itemAt(pointScene, ui.View->transform()); //获取光标下的绘图项
	if (item != NULL) //有绘图项
	{
		QPointF pointItem = item->mapFromScene(pointScene); //转换为绘图项的局部坐标
		labItemCord->setText(QString::asprintf("Item 坐标:%.0f,%.0f", pointItem.x(), pointItem.y()));
	}
}

窗口变化大小时的事件:

//窗口变化大小时的事件
void sample8_4QGraphicsView::resizeEvent(QResizeEvent *event)
{ 
	Q_UNUSED(event);
	//Graphics View坐标,左上角总是(0,0),宽度=,长度=
	ui.labViewSize->setText(QString::asprintf("Graphics View坐标,左上角总是(0,0),宽度=%d,高度=%d",
		ui.View->width(), ui.View->height()));

	QRectF  rectF = ui.View->sceneRect(); //Scene的矩形区
	ui.LabSceneRect->setText(QString::asprintf("QGraphicsView::sceneRect=(Left,Top,Width,Height)=%.0f,%.0f,%.0f,%.0f",
		rectF.left(), rectF.top(), rectF.width(), rectF.height()));
}

构造Graphics View的各项:

//构造Graphics View的各项
void sample8_4QGraphicsView::iniGraphicsSystem()
{
	QRectF   rect(-200, -100, 400, 200);//左上角坐标,宽度,高度
	scene = new QGraphicsScene(rect); //scene逻辑坐标系定义
	ui.View->setScene(scene);


	//画一个矩形框,大小等于scene
	QGraphicsRectItem *item = new QGraphicsRectItem(rect); //矩形框正好等于scene的大小
	item->setFlags(QGraphicsItem::ItemIsSelectable     //可选,可以有焦点,但是不能移动
		| QGraphicsItem::ItemIsFocusable);
	QPen    pen;
	pen.setWidth(2);
	item->setPen(pen);
	//item->setPos(500,0);//缺省位置在scene的(0,0)
	scene->addItem(item);

	//一个位于scene中心的椭圆,测试局部坐标
	QGraphicsEllipseItem *item2 = new QGraphicsEllipseItem(-100, -50, 200, 100); //矩形框内创建椭圆,绘图项的局部坐标,左上角(-100,-50),宽200,高100
	item2->setPos(0, 0);//设置椭圆中心位置
	item2->setBrush(QBrush(Qt::blue));
	item2->setFlags(QGraphicsItem::ItemIsMovable //可移动
		| QGraphicsItem::ItemIsSelectable  //可选择
		| QGraphicsItem::ItemIsFocusable); //可获得焦点
	scene->addItem(item2);

	//一个圆,中心位于scene的边缘
	QGraphicsEllipseItem *item3 = new QGraphicsEllipseItem(-50, -50, 100, 100); //矩形框内创建椭圆,绘图项的局部坐标,左上角(-100,-50),宽200,高100
	item3->setPos(rect.right(), rect.bottom());//设置圆中心位置
	item3->setBrush(QBrush(Qt::red));
	item3->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
	scene->addItem(item3);

	scene->clearSelection();
	//item->setSelected(true);

	//ui.View->setDragMode(QGraphicsView::RubberBandDrag);
}

运行结果如下:

"QWGraphicsView.cpp" 文件代码如下:

#include "QWGraphicsView.h"

#include    <QMouseEvent>
#include    <QPoint>


QWGraphicsView::QWGraphicsView(QWidget *parent)
	: QGraphicsView(parent)
{
}

QWGraphicsView::~QWGraphicsView()
{
}

//鼠标移动事件
void QWGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
	QPoint point = event->pos();//QGraphicsView的坐标
	emit mouseMovePoint(point); //释放信号
	QGraphicsView::mouseMoveEvent(event);
}

//鼠标左键按下事件
void QWGraphicsView::mousePressEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton)
	{
		QPoint point = event->pos();//QGraphicsView的坐标
		emit mouseClicked(point);//释放信号
	}
	QGraphicsView::mousePressEvent(event);
}

"sample8_4QGraphicsView.cpp"  文件代码如下:

#include "sample8_4QGraphicsView.h"

#include  "ui_sample8_4QGraphicsView.h"
#include   <QGraphicsEllipseItem>


//解决QT中中文显示乱码问题
#pragma execution_character_set("utf-8")


sample8_4QGraphicsView::sample8_4QGraphicsView(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	labViewCord = new QLabel("View 坐标:");
	labViewCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labViewCord);

	labSceneCord = new QLabel("Scene 坐标:");
	labSceneCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labSceneCord);

	labItemCord = new QLabel("Item 坐标:");
	labItemCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labItemCord);

	ui.View->setCursor(Qt::CrossCursor);
	ui.View->setMouseTracking(true);
	ui.View->setDragMode(QGraphicsView::RubberBandDrag);

	QObject::connect(ui.View, SIGNAL(mouseMovePoint(QPoint)),
		this, SLOT(on_mouseMovePoint(QPoint)));

	QObject::connect(ui.View, SIGNAL(mouseClicked(QPoint)),
		this, SLOT(on_mouseClicked(QPoint)));

	iniGraphicsSystem();
}

//鼠标移动事件,point是 GraphicsView的坐标,物理坐标
void sample8_4QGraphicsView::on_mouseMovePoint(QPoint point)
{
	labViewCord->setText(QString::asprintf("View 坐标:%d,%d", point.x(), point.y()));
	QPointF pointScene = ui.View->mapToScene(point); //转换到Scene坐标
	labSceneCord->setText(QString::asprintf("Scene 坐标:%.0f,%.0f", pointScene.x(), pointScene.y()));
}

//鼠标单击事件
void sample8_4QGraphicsView::on_mouseClicked(QPoint point)
{
	QPointF pointScene = ui.View->mapToScene(point); //转换到Scene坐标
	QGraphicsItem  *item = NULL;
	item = scene->itemAt(pointScene, ui.View->transform()); //获取光标下的绘图项
	if (item != NULL) //有绘图项
	{
		QPointF pointItem = item->mapFromScene(pointScene); //转换为绘图项的局部坐标
		labItemCord->setText(QString::asprintf("Item 坐标:%.0f,%.0f", pointItem.x(), pointItem.y()));
	}
}

//构造Graphics View的各项
void sample8_4QGraphicsView::iniGraphicsSystem()
{
	QRectF   rect(-200, -100, 400, 200);//左上角坐标,宽度,高度
	scene = new QGraphicsScene(rect); //scene逻辑坐标系定义
	ui.View->setScene(scene);


	//画一个矩形框,大小等于scene
	QGraphicsRectItem *item = new QGraphicsRectItem(rect); //矩形框正好等于scene的大小
	item->setFlags(QGraphicsItem::ItemIsSelectable     //可选,可以有焦点,但是不能移动
		| QGraphicsItem::ItemIsFocusable);
	QPen    pen;
	pen.setWidth(2);
	item->setPen(pen);
	//item->setPos(500,0);//缺省位置在scene的(0,0)
	scene->addItem(item);

	//一个位于scene中心的椭圆,测试局部坐标
	QGraphicsEllipseItem *item2 = new QGraphicsEllipseItem(-100, -50, 200, 100); //矩形框内创建椭圆,绘图项的局部坐标,左上角(-100,-50),宽200,高100
	item2->setPos(0, 0);//设置椭圆中心位置
	item2->setBrush(QBrush(Qt::blue));
	item2->setFlags(QGraphicsItem::ItemIsMovable //可移动
		| QGraphicsItem::ItemIsSelectable  //可选择
		| QGraphicsItem::ItemIsFocusable); //可获得焦点
	scene->addItem(item2);

	//一个圆,中心位于scene的边缘
	QGraphicsEllipseItem *item3 = new QGraphicsEllipseItem(-50, -50, 100, 100); //矩形框内创建椭圆,绘图项的局部坐标,左上角(-100,-50),宽200,高100
	item3->setPos(rect.right(), rect.bottom());//设置圆中心位置
	item3->setBrush(QBrush(Qt::red));
	item3->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
	scene->addItem(item3);

	scene->clearSelection();
	//item->setSelected(true);

	//ui.View->setDragMode(QGraphicsView::RubberBandDrag);
}

//窗口变化大小时的事件
void sample8_4QGraphicsView::resizeEvent(QResizeEvent *event)
{ 
	Q_UNUSED(event);
	//Graphics View坐标,左上角总是(0,0),宽度=,长度=
	ui.labViewSize->setText(QString::asprintf("Graphics View坐标,左上角总是(0,0),宽度=%d,高度=%d",
		ui.View->width(), ui.View->height()));

	QRectF  rectF = ui.View->sceneRect(); //Scene的矩形区
	ui.LabSceneRect->setText(QString::asprintf("QGraphicsView::sceneRect=(Left,Top,Width,Height)=%.0f,%.0f,%.0f,%.0f",
		rectF.left(), rectF.top(), rectF.width(), rectF.height()));
}

"main.cpp"  文件代码如下:

#include "sample8_4QGraphicsView.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	sample8_4QGraphicsView w;
	w.show();
	return a.exec();
}

《Qt5/6 C++开发指南》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2248599.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【eNSP】动态路由协议RIP和OSPF

动态路由RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;和OSPF&#xff08;Open Shortest Path First&#xff0c;开放式最短路径优先&#xff09;是两种常见的动态路由协议&#xff0c;它们各自具有不同的特点和使用场景。本篇会对这两种协…

差分 + 模拟,CF 815A - Karen and Game

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 815A - Karen and Game 二、解题报告 1、思路分析 一个经典的差分数组的…

vue3【实战】响应式的登录界面

效果预览 WEB 端效果 移动端效果 技术方案 vue3 vite Element Plus VueRouter UnoCSS TS vueUse AutoImport 技术要点 响应式设计 移动端&#xff1a;图片切换为绝对定位&#xff0c;下移一层&#xff0c;成为背景图片 <el-imageclass"w-screen h-screen lt-md…

加速科技精彩亮相中国国际半导体博览会IC China 2024

11月18日—20日&#xff0c;第二十一届中国国际半导体博览会&#xff08;IC China 2024&#xff09;在北京国家会议中心顺利举办&#xff0c;加速科技携重磅产品及全系测试解决方案精彩亮相&#xff0c;加速科技创始人兼董事长邬刚受邀在先进封装创新发展论坛与半导体产业前沿与…

php反序列化1_常见php序列化的CTF考题

声明&#xff1a; 以下多内容来自暗月师傅我是通过他的教程来学习记录的&#xff0c;如有侵权联系删除。 一道反序列化的CTF题分享_ctf反序列化题目_Mr.95的博客-CSDN博客 一些其他大佬的wp参考&#xff1a;php_反序列化_1 | dayu’s blog (killdayu.com) 序列化一个对象将…

RustDesk 搭建

RustDesk 服务端下载&#xff1a;https://github.com/rustdesk/rustdesk-server/releases RustDesk 客户端下载&#xff1a;https://github.com/rustdesk/rustdesk/releases RustDesk 官方部署教程&#xff1a;https://rustdesk.com/docs/zh-cn/ 1&#xff1a;RustDesk 概览# 1…

Qt读写Usb设备的数据

Qt读写Usb设备的数据 问题:要读取usb设备进行通讯&#xff0c;qt好像没有对应的库支持。解决&#xff1a;libusbwindow下载 :Linux下载: QtUsb 开源的第三方库库里面的函数说明&#xff1a;window版本&#xff1a;Linux中也提供的直接下载测试代码&#xff1a;库下载&#xff1…

模板初阶,STL简介(C++)

1.模板 1.1泛型编程 在之前的文章中讲过C支持函数重载&#xff0c;比如实现一个交换函数&#xff0c;可以是不同的数据类型&#xff0c;但是这样&#xff0c;需要增加大量函数&#xff0c;且可维护度比较低。 如&#xff1a; void Swap(int& left, int& right) {int …

Cannot find a valid baseurl for repo: centos-sclo-rh/x86_64

yum install 报错: Cannot find a valid baseurl for repo: centos-sclo-rh/x86_64 CentOS7的SCL源在2024年6月30日停止维护了。 当scl源里面默认使用了centos官方的地址&#xff0c;无法连接&#xff0c;需要替换为阿里云。 cd /etc/yum.repos.d/ 找到 CentOS-SCLo-scl.repo 和…

蓝桥杯不知道叫什么题目

小蓝有一个整数&#xff0c;初始值为1&#xff0c;他可以花费一些代价对这个整数进行变换。 小蓝可以花贵1的代价将教数增加1。 小蓝可以花费3的代价将整数增加一个值,这个值是整数的数位中最大的那个(1到9) .小蓝可以花费10的代价将整数变为原来的2倍, 例如&#xff0c;如果整…

2024年11月HarmonyOS应用开发者高级认证全新题库

注意事项&#xff1a;切记在考试之外的设备上打开题库进行搜索&#xff0c;防止切屏三次考试自动结束&#xff0c;题目是乱序&#xff0c;每次考试&#xff0c;选项的顺序都不同&#xff0c;作者已于2024年11月22日又更新了一波题库&#xff0c;题库正确率99%&#xff01; 新版…

技术文档的高质量翻译对俄罗斯汽车推广的影响

进入新市场需要的不仅仅是一个伟大的产品&#xff1b;它要求深入了解当地消费者的期望、法规和文化差异。对于希望在俄罗斯取得成功的国际汽车制造商来说&#xff0c;技术文件的质量是一个关键因素。手册、规范和服务指南在产品和用户之间形成了直接的桥梁&#xff0c;影响着客…

【组件】前端ElementUi 下拉Tree树形组件 带模糊搜索自动展开高亮功能 树结构 封装为组件使用

【组件】前端ElementUi 下拉Tree树形组件 带模糊搜索自动展开高亮功能 树结构 【组件】前端ElementUi 下拉Tree树形组件 带模糊 https://live.csdn.net/v/436057 单独使用 <template><div><el-popoverstyle"overflow-y: auto; "placement"bottom…

论文阅读:Dual-disentangled Deep Multiple Clustering

目录 摘要 引言 模型 实验 数据集 实验结果 结论 摘要 多重聚类近年来引起了广泛关注&#xff0c;因为它能够从不同的角度揭示数据的多种潜在结构。大多数多重聚类方法通常先通过控制特征之间的差异性来提取特征表示&#xff0c;然后使用传统的聚类方法&#xff08;如 …

SQL 复杂查询

目录 复杂查询 一、目的和要求 二、实验内容 &#xff08;1&#xff09;查询出所有水果产品的类别及详情。 查询出编号为“00000001”的消费者用户的姓名及其所下订单。&#xff08;分别采用子查询和连接方式实现&#xff09; 查询出每个订单的消费者姓名及联系方式。 在…

thread_id_key != 0x7777(`fibers` 包与 Node.js 16 及以上版本存在兼容性问题)

文章目录 fibers4.0.3 与 node-v16.13.2-win-x64 的兼容性1. Node.js 版本兼容性2. 特定包版本 (fibers4.0.3)3. 解决方案和替代方案 结论解决方案 运行yarn serve 启动项目&#xff0c;就会弹出上述错误。 fibers4.0.3 与 node-v16.13.2-win-x64 的兼容性 要判断 fibers4.0.3…

数据结构 (6)栈的应用举例

1. 递归调用 递归函数在执行时&#xff0c;会将每一层的函数调用信息&#xff08;包括局部变量、参数和返回地址&#xff09;存储在栈中。当递归函数返回时&#xff0c;这些信息会从栈中弹出&#xff0c;以便恢复之前的执行状态。栈的后进先出&#xff08;LIFO&#xff09;特性…

网络安全在数字时代保护库存数据中的作用

如今&#xff0c;通过软件管理库存已成为一种标准做法。企业使用数字工具来跟踪库存水平、管理供应链和规划财务。 然而&#xff0c;技术的便利性也带来了网络威胁的风险。黑客将库存数据视为有价值的目标。保护这些数据不仅重要&#xff0c;而且必不可少。 了解网络安全及其…

php常用伪协议整理

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文整理php常见的伪协议 php伪协议介绍 直观点&#xff0c;就是php可以识别的协议。 类似于我们访问网站的http协议&#xff0c;我们用浏览器访问我们自己本地文件的file协议等。 php可以识别这些协议&#xf…

【软件入门】Git快速入门

Git快速入门 文章目录 Git快速入门0.前言1.安装和配置2.新建版本库2.1.本地创建2.2.云端下载 3.版本管理3.1.添加和提交文件3.2.回退版本3.2.1.soft模式3.2.2.mixed模式3.2.3.hard模式3.2.4.使用场景 3.3.查看版本差异3.4.忽略文件 4.云端配置4.1.Github4.1.1.SSH配置4.1.2.关联…