QT图形/视图架构详解(一)

场景、视图与图形项

图形/视图架构主要由 3 个部分组成,即场景、视图和图形项,三者的关系如图所示:

场景、视图和图形项的关系

场景(QGraphicsScene 类)

场景不是界面组件,它是不可见的。场景是一个抽象的管理图形项的容器,我们可以向场景添加图形项,可以获取场景中的某个图形项。场景主要具有如下一些功能。

• 提供管理大量图形项的快速接口。

• 将事件传播给每个图形项。

• 管理每个图形项的状态,例如选择状态、焦点状态等。

• 管理未经变换的渲染功能,主要用于打印。

视图(QGraphicsView类)

QGraphicsView 是图形/视图架构中的视图组件。所以它是一个界面组件,用于显示场景中的内容。可以为一个场景设置多个视图,用于对同一个场景提供不同的显示界面。

在上图中,虚线框部分是一个场景,视图 1(场景外部的实线矩形框)比场景大,显示场景的全部内容。默认情况下,当视图大于场景时,场景在视图的中央位置显示,也可以通过设置视图的 Alignment 属性来控制场景在视图中的显示位置。视图 2(场景内部的实线矩形框)比场景小,视图 2 只能显示场景的部分内容,但是会自动提供卷滚条实现在整个场景内移动。

图形项(QGraphicsItem类)

图形项相当于模型中的数据,一个图形项存储了绘制这个图形项的各种参数,场景管理所

有图形项,而视图组件则负责绘制这些图形项。

QGraphicsItem 支持如下一些操作:

• 鼠标事件响应。

• 键盘输入,以及按键事件。

• 拖放操作。

• 支持组合,可以是父子图形项关系组合,也可以通过 QGraphicsItemGroup 类进行组合。

总结:场景是图形项的容器,可以在场景中添加很多图形项,每个图形项就是一 个对象。视图是显示场景的全部或部分区域的视口,也就是显示场景中的图形项,这些图形项可以被选择和拖动。

图形/视图架构的坐标系

图形/视图架构有 3 个有效的坐标系:场景坐标系、视图坐标系、图形项坐标系。3 个坐标系的

示意如图所示。

绘图的时候,场景坐标系等价于 QPainter的逻辑坐标系,一般以场景的中心为原点;视图坐标系与绘图设备坐标系相同,是物理坐标系,默认以左上角为原点;图形项坐标系是局部逻辑坐标系,一般以图形项的中心为原点。

图形项坐标系

图形项使用自己的局部坐标系,通常以其中心为原点(0, 0),这也是各种坐标变换的中心。绘制图形项时只需考虑其局部坐标系,QGraphicsScene 和 QGraphicsView 会自动进行坐标变换。

图形项的位置是指其中心在父对象坐标系中的坐标。 其父对象可以是场景或者其他父图形项。

QGraphicsItem 的大多数函数都在其局部坐标系上操作,QGraphicsItem::pos()是仅有的几个例外之一,它返回的是图形项在父图形项坐标系中的坐标,如果是顶层图形项,则返回的是在场景中的坐标。

视图坐标系

视图坐标系就是视图组件的物理坐标系,单位是像素。视图坐标系只与视图组件或视口有关,而与观察的场景无关。QGraphicsView 视口的左上角坐标总是(0,0)。

所有的鼠标事件、拖放事件的坐标首先是由视图坐标系定义的,然后用户需要将这些坐标映射为场景坐标,以便和图形项交互。

场景坐标系

场景坐标系定义了所有图形项的基础坐标,场景坐标系描述了每个顶层图形项的位置。创建场景时可以定义场景矩形区域的坐标范围。

scene= new QGraphicsScene(-400,-300,800,600); 

这样定义的 scene 是左上角坐标为(−400,−300)、宽度为 800 像素、高度为 600 像素的矩形区域,单位是像素。

每个图形项在场景里有一个位置坐标,由函数 QGraphicsItem::scenePos()给出,还有一个图形项边界矩形,由函数 QGraphicsItem::sceneBoundingRect()给出。边界矩形可以使场景知道场景的哪个区域发生了变化。场景发生变化时会发射 QGraphicsScene::changed()信号,参数是场景内的矩形区域列表,表示发生变化的矩形区域。

坐标映射

在场景中操作图形项时,会进行场景到图形项、图形项到图形项或视图到场景的坐标变换。例如,在 QGraphicsView 的视口上点击鼠标时,通过函数 QGraphicsView::mapToScene() 可以将视图坐标映射为场景坐标,然后用 QGraphicsScene::itemAt()函数可以获取场景中鼠标光标 处的图形项。

相关类的介绍

图形/视图架构主要的类包括视图类 QGraphicsView、场景类 QGraphicsScene,以及各种图形

项类,图形项类的基类是 QGraphicsItem。

QGraphicsView 类

QGraphicsView 是用于观察场景的物理窗口,其视口坐标系等同于显示设备的物理坐标系,也可以对 QGraphicsView 的坐标系进行平移、旋转、缩放等变换。

QGraphicsView 的主要接口函数如下表所示,一般设置函数有一个对应的读取函数,set_XXX对应get_XXX,这里只列出设置函数。

QGraphicsScene 类

QGraphicsScene 是用于管理图形项的场景,是图形项的容器。主要接口函数如下表所示,表中仅列出函数的返回值类型,省略了输入参数。

QGraphicsItem类

QGraphicsItem 是所有图形项类的基类,我们可以从 QGraphicsItem 继承定义自己的图形项。Qt 定义了一些常见的图形项,这些常见的图形项类的继承关系如下所示。

例如要设置图形项是一张图像,可以使用QGraphicsPixmapItem类和QImage、QPixmap配合设置设置显示的图像。

有关图形项操作的函数,主要的接口函数如下表所示,表中仅列出函数的返回值类型,省略了输入参数。

函数 setFlags()用于设置图形项的操作标志,包括可选择、可移动、可获取焦点等。函数 setPos()用于设置图形项在父图形项中的坐标,如果没有父图形项,则是在场景中的坐标。函数 setZValue()用于控制图形项的叠放次序,当多个图形项重叠时,zValue 值越大的越显示在前面,相当于优先级,值越大,优先级越高。

示例程序解读

该程序的主要功能:

• 工作区是一个 TGraphicsView 组件,其作为绘图的视图组件。

• 程序中创建了一个 QGraphicsScene 场景,场景的大小就是下图中的实线矩形框的大小。

• 若改变窗口大小,当视图大于场景时,矩形框总是居于视图的中央;当视图小于场景时,在视图窗口中会自动出现卷滚条。

• 椭圆正好处于场景的中央,圆位于场景的右下角。当图形项位置不在场景的矩形框中时,图形项也是可以显示的。

• 当鼠标光标在窗口上移动时,状态栏上会显示当前光标位置在视图中的坐标和在场景中的坐标。在某个图形项上点击鼠标时,状态栏上还会显示图形项中的局部坐标。

自定义QGraphicsView视图组件

为了实现一些定制化功能,从 QGraphicsView 继承定义了一个类 TGraphicsView ,重新实现事件处理函数mouseMoveEvent()和 mousePressEvent(),把鼠标事件转换为自定义信号,这样就可以在使用TGraphicsView 组件的主窗口里设计槽函数响应这些鼠标事件。

类声明与定义如下:

//.h文件
#ifndef TGRAPHICSVIEW_H
#define TGRAPHICSVIEW_H#include <QObject>
#include <QGraphicsView>//自定义TGraphicsView类继承QGraphicsView类
class TGraphicsView : public QGraphicsView
{Q_OBJECTprotected:    //重新实现下面两个函数void mouseMoveEvent(QMouseEvent *event);void mousePressEvent(QMouseEvent *event);public:TGraphicsView(QWidget *parent = nullptr);signals://信号会附带发送当前鼠标坐标void mouseMovePoint(QPoint point);void mouseClicked(QPoint point);
};#endif // TGRAPHICSVIEW_H///.cpp文件
#include    "tgraphicsview.h"
#include    <QMouseEvent>
#include    <QPoint>void TGraphicsView::mouseMoveEvent(QMouseEvent *event)
{//鼠标移动事件QPoint point=event->pos();      //QGraphicsView的坐标emit mouseMovePoint(point);     //释放信号QGraphicsView::mouseMoveEvent(event);   //调用父类的事件函数
}void TGraphicsView::mousePressEvent(QMouseEvent *event)
{ //鼠标左键按下事件if (event->button()==Qt::LeftButton){QPoint point=event->pos();  //QGraphicsView的坐标emit mouseClicked(point);   //释放信号}QGraphicsView::mousePressEvent(event);  //父类事件
}//构造函数
TGraphicsView::TGraphicsView(QWidget *parent):QGraphicsView(parent)
{}

这两个事件处理函数 mouseMoveEvent()和 mousePressEvent(),并定义了两个信号 mouseMovePoint()和 mouseClicked()。这两个函数的参数 event 都是 QMouseEvent 类型,如果鼠标发生相应的事件会将将发生的event传入事件处理函数。

通过 event->pos()可以获取鼠标光标在视图中的坐标 point,在发射自定义信号 mouseMovePoint()和 mouseClicked()时将 point 作为信号的参数。在其他地方可以使用connect()将该信号与相应的槽函数连接后就可以实现相应的功能。

主窗口

在主窗口函数中,设置视图的属性,连接视图的鼠标事件与槽函数,然后在视图中创建场景并将其与界面上的视图组件 view 关联起来,在场景中添加图形项,这里需要注意图形项的一些属性设置。若不调用函数 setPos()设置图形项在场景中的位置,默认位置为(0, 0)。

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);//状态栏设计labViewCord=new QLabel("View 坐标:", this);labViewCord->setMinimumWidth(150);ui->statusBar->addWidget(labViewCord);labSceneCord=new QLabel("Scene 坐标:", this);labSceneCord->setMinimumWidth(150);ui->statusBar->addWidget(labSceneCord);labItemCord=new QLabel("Item 坐标:", this);labItemCord->setMinimumWidth(150);ui->statusBar->addWidget(labItemCord);ui->view->setCursor(Qt::CrossCursor);   //十字光标ui->view->setMouseTracking(true);       //鼠标跟踪ui->view->setDragMode(QGraphicsView::RubberBandDrag);   //矩形选择框// ui->view->setDragMode(QGraphicsView::ScrollHandDrag);connect(ui->view,SIGNAL(mouseMovePoint(QPoint)),this, SLOT(do_mouseMovePoint(QPoint)));connect(ui->view,SIGNAL(mouseClicked(QPoint)),this, SLOT(do_mouseClicked(QPoint)));iniGraphicsSystem();    //Graphics View结构初始化
}//创建Graphics View结构中的各项
void MainWindow::iniGraphicsSystem()
{QRectF   rect(-200,-100,400,200);  //该坐标是在view中的坐标scene=new QGraphicsScene(rect,this); //scene逻辑坐标系定义ui->view->setScene(scene);      //为视图设置场景//画一个矩形框,大小等于sceneQGraphicsRectItem   *item=new QGraphicsRectItem(rect);  //矩形框正好等于scene的大小//    item->setFlag(QGraphicsItem::ItemIsSelectable);         //可选中//    item->setFlag(QGraphicsItem::ItemIsFocusable);          //可以获得焦点//    item->setFlag(QGraphicsItem::ItemIsMovable,false);      //不能移动//可选,可以有焦点,但是不能移动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,高100item2->setPos(0,0);     //图形项在场景中的坐标item2->setBrush(QBrush(Qt::blue));item2->setFlag(QGraphicsItem::ItemIsMovable);      //能移动item2->setFlag(QGraphicsItem::ItemIsSelectable);   //可选中item2->setFlag(QGraphicsItem::ItemIsFocusable);    //可以获得焦点//    item2->setFlags(QGraphicsItem::ItemIsMovable//                    | QGraphicsItem::ItemIsSelectable//                    | QGraphicsItem::ItemIsFocusable);scene->addItem(item2);//一个圆,中心位于scene的边缘QGraphicsEllipseItem   *item3=new QGraphicsEllipseItem(-50,-50,100,100); //矩形框内创建椭圆,绘图项的局部坐标,左上角(-100,-50),宽200,高100item3->setPos(rect.right(),rect.bottom());        //图形项在场景中的坐标item3->setBrush(QBrush(Qt::red));item3->setFlag(QGraphicsItem::ItemIsMovable);      //能移动item3->setFlag(QGraphicsItem::ItemIsSelectable);   //可选中item3->setFlag(QGraphicsItem::ItemIsFocusable);    //可以获得焦点//    item3->setFlags(QGraphicsItem::ItemIsMovable//                    | QGraphicsItem::ItemIsSelectable//                    | QGraphicsItem::ItemIsFocusable);scene->addItem(item3);scene->clearSelection();
}

对于视图属性的设置:

• setCursor(Qt::CrossCursor):将鼠标光标设置为十字形。

• setMouseTracking(true):开启鼠标跟踪,在鼠标移动时就会产生 mouseMove 事件。默认是不开启鼠标跟踪的,那么只有在按下鼠标某个键时才会产生 mouseMove 事件。

• setDragMode(QGraphicsView::RubberBandDrag):在场景的背景上点击并拖动鼠标时,显示 一个矩形框。默认是不响应(QGraphicsView::NoDrag),其值还可以设置为 QGraphicsView:: ScrollHandDrag,拖动鼠标时鼠标光标变成手形,拖动鼠标就会使卷滚条移动。

关联信号与槽函数

连接的两个自定义槽函数用于与界面上的 TGraphicsView 组件的两个信号关联,在鼠标移动时显示视图中的坐标和场景中的坐标,在点击鼠标时显示图形项的局部坐标。

槽函数定义如下所示:


//鼠标移动,point是 GraphicsView的坐标,物理坐标
void MainWindow::do_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 MainWindow::do_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()));}
}

鼠标事件中,参数 point 是鼠标在视图中的坐标,使用 QGraphicsView 的 mapToScene()函数可以将此坐标变换为场景中的坐标。先用 QGraphicsView 的mapToScene()函数将此坐标变换为场景中的坐标 pointScene,然后用 QGraphicsScene 的 itemAt()函数获得光标处的图形项。如果鼠标光标处有图形项,就用图形项的 mapFromScene()函数将pointScene 变换为图形项的局部坐标 pointItem。

自定义TGraphicsView的UI提升

我们使用时需要的是TGraphicsView,但是QT可选组件中只有GraphicsView,因此需要将视图组件升级为 TGraphicsView 类。升级方法如下所示,之前在QT界面设计中添加的是QGraphicsView,右键该组件点击提升为----->TGraphicView即可。这是使用自定义界面组件的一种方法。

为了测试视图与场景的尺寸变化,主窗口还重定义了事件处理函数 resizeEvent(),以便在窗口大小变化时,显示视图区域和场景的大小信息。其代码如下:

//窗口变化大小时的事件
void MainWindow::resizeEvent(QResizeEvent *event)
{//    Q_UNUSED(event);//Graphics View坐标,左上角总是(0,0),宽度=,长度=QString str=QString::asprintf("Graphics View坐标,左上角总是(0,0),宽度=%d,高度=%d",ui->view->width(),ui->view->height());ui->labViewSize->setText(str);//    ui->labViewSize->setText(QString::asprintf("Graphics View坐标,左上角总是(0,0),宽度=%d,高度=%d",//                             ui->view->width(),ui->view->height()));QRectF  rectF=ui->view->sceneRect(); //场景的矩形区QString str2=QString::asprintf("QGraphicsView::sceneRect=(Left,Top,Width,Height)""=%.0f,%.0f,%.0f,%.0f", rectF.left(),rectF.top(),rectF.width(),rectF.height());ui->labSceneRect->setText(str2);//    ui->labSceneRect->setText(QString::asprintf("QGraphicsView::sceneRect=(Left,Top,Width,Height)=%.0f,%.0f,%.0f,%.0f",//                              rectF.left(),rectF.top(),rectF.width(),rectF.height()));event->accept();
}

通过测试,程序在窗口大小改变时,labViewSize 显示的视图宽度和高度是随窗口大小变化而变化的,而 labSceneRect 显示的场景的矩形区大小是固定的,总是(−200, −100, 400, 200)。

如下图,将程序窗口缩小,视图也会变小,显示的内容也会被隐藏一部分,但是场景是尺寸是不变的,所以视图是用来“看”的,而场景是用“存”的,视图中虽然有些组件看不见了,但是这些组件确确实实还在场景中,这也是为什么在视图和图形项中要套一层场景,这样更方便管理。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Towards Frame Rate Agnostic Multi-object Tracking—迈向帧率无关的多目标跟踪

Towards Frame Rate Agnostic Multi-object Tracking—迈向帧率无关的多目标跟踪 发表在IJCV 2023年 作者&#xff1a;Weitao Feng, Lei Bai, Yongqiang Yao, Fengwei Yu & Wanli Ouyang 研究目标&#xff1a;多目标跟踪的帧率无关性研究 IJCV 在计算机视觉领域的影响力非常…

最新消息!ChatGPT已集成到苹果操作系统!

12月11日&#xff0c;OpenAI宣布ChatGPT将集成到苹果iOS、iPadOS和macOS操作系统中&#xff0c;用户可以直接在这些设备上访问ChatGPT的功能。 通过此次宣布内容来看&#xff0c;ChatGPT不再局限于单独的应用程序&#xff0c;用户可以在苹果设备上更便捷地使用它。这意味着&…

该用户不拥有该设备20018

调用接口查询或操作托管设备时报错无权限 第一步&#xff1a;确认调用接口需要的权限 这里以关闭设备加密接口为例&#xff1a;/api/lapp/device/encrypt/off&#xff0c;官网接口文档上注明了需要Config权限。注&#xff1a;调用此类接口时需要用使用大账号token&#xff0c;不…

【MySql】数据库索引概念及其作用详细介绍

目录 1. 为什么使用索引 2. 索引及其优缺点 2.1 索引的概述 2.2 优点 2.3 缺点 3. InnoDB中索引的推演 3.1 索引之前的查找 3.2 设计索引 1. 一个简单的索引设计方案 2. InnoDB中的索引方案 3.3 常见索引概念 1.聚簇索引 2.二级索引(辅助索引、非聚簇索引) 3.联合…

ESP32外设学习部分--SPI篇

SPI学习 前言 我个人以为开始学习一个新的单片机最好的方法就是先把他各个外设给跑一遍&#xff0c;整体了解一下他的功能&#xff0c;由此记录一下我学习ESP32外设的过程&#xff0c;防止以后忘记。 SPI 配置步骤 SPI总线初始化 spi_bus_config_t buscfg {.miso_io_num …

vue3+setup使用rtsp视频流实现实时监控,全屏,拍摄,自动拍摄等功能(纯前端)

vue3setup使用rtsp视频流实现实时监控&#xff0c;全屏&#xff0c;拍摄&#xff0c;自动拍摄等功能(纯前端) 概要 本文介绍了如何在Vue应用中通过WebRTC技术获取摄像头的rtsp视频流&#xff0c;同时展示了实时监控&#xff0c;全屏&#xff0c;拍摄&#xff0c;自动拍摄等功…

【源码阅读系列】(五)进程间通信(二)

进程间通信(二) 这一部分主要会介绍Android中特有的几个IPC机制。分别是: Intent、Binder、AIDL、ContentProvider https://juejin.cn/post/7244018340880007226 https://juejin.cn/post/6844903764986462221 Binder https://juejin.cn/post/7244018340880007226 https://j…

机器学习(ML)在发射机识别与资源管理的应用

电子战&#xff08;EW&#xff09;涉及在受干扰的频谱环境中&#xff0c;通过多个无线电频率传感和发射平台进行非合作交互。操作人员需要管理频谱资源、共享关键情报&#xff0c;并有效干扰威胁发射器。现代RF系统的复杂性和威胁发射器的敏捷性&#xff0c;要求系统能够以机器…

高项 - 信息化发展

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 博文更新参考时间点&#xff1a;2024-11-09 高项 - 章节与知识点汇总&#xff1a;点击跳转 文章目录 高项 - 信息化发展信息与信息化信息信息系统信息化 现代化基础设施新型基础设施建设工业互联网车联网 现代化创…

TaskBuilder内设置任擎服务器

TaskBuilder内设置任擎服务器 在使用TaskBuilder进行软件开发时&#xff0c;必须要先连接到任擎服务器&#xff08;后续文档所说的服务器如果不特别注明&#xff0c;皆指任擎服务器&#xff09;才能继续操作&#xff0c;因为使用TaskBuilder开发所需的数据模型、后台服务和前端…

六、nginx负载均衡

负载均衡&#xff1a;将四层或者七层的请求分配到多台后端的服务器上。 从而分担整个业务的负载。提高系统的稳定性&#xff0c;也可以提高高可用&#xff08;备灾&#xff0c;其中一台后端服务器如果发生故障不影响整体业务&#xff09;. 负载均衡的算法 round robin 轮询 r…

代码随想录训练营第十七天| 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

654.最大二叉树 题目链接/文章讲解&#xff1a; 代码随想录 视频讲解&#xff1a;又是构造二叉树&#xff0c;又有很多坑&#xff01;| LeetCode&#xff1a;654.最大二叉树_哔哩哔哩_bilibili 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子…

面向对象进阶:多态

黑马程序员Java个人笔记 BV17F411T7Ao p129~132 目录 多态 多态调用成员的特点 调用成员变量 调用成员方法 理解 多态的优势 解耦合 多态的弊端 解决方案&#xff1a;强制类型转换 instanceof jdk14新特性&#xff0c;将判断和强转放一起 总结 多态 多态调…

系统思考沙盘模拟

今天《收获季节》沙盘模拟的第一天课程圆满结束&#xff0c;不仅从管理技巧的角度深入展开&#xff0c;还让大家体验了决策带来的直接影响。明天&#xff0c;我们将带领学员从系统思考和全局视角来重新审视这些问题&#xff0c;找到更深层的因果关系和系统性改进的思路。期待更…

AI 赋能直播新玩法 —— 无人直播,它到底藏着多少未知?

​ 在数字浪潮汹涌澎湃的时代&#xff0c;直播领域正历经一场前所未有的变革&#xff0c;AI 赋能的无人直播宛如一颗神秘新星&#xff0c;闯入大众视野&#xff0c;撩拨着人们的好奇心&#xff0c;可它究竟潜藏着多少待解谜团&#xff0c;尚无人能完全洞悉。 从技术的幽微深处…

【深度学习】热力图绘制

热力图&#xff08;Heatmap&#xff09;是一种数据可视化方法&#xff0c;通过颜色来表示数据矩阵中的数值大小&#xff0c;以便更直观地展示数据的分布和模式。热力图在许多领域中都有应用&#xff0c;尤其在统计分析、机器学习、数据挖掘等领域&#xff0c;能够帮助我们快速识…

ssm-springmvc-学习笔记

简介 简单的来说&#xff0c;就是一个在表述层负责和前端数据进行交互的框架 帮我们简化了许多从前端获取数据的步骤 springmvc基本流程 用户在原本的没有框架的时候请求会直接调用到controller这个类&#xff0c;但是其步骤非常繁琐 所以我们就使用springmvc进行简化 当用…

Axure原型设计:打造科技感可视化大屏元件

在数字化时代&#xff0c;数据可视化大屏已成为企业展示数据、监控业务状态的重要工具。一个设计精良的大屏不仅要有丰富的信息展示&#xff0c;更需具备强烈的科技感&#xff0c;以吸引观众的注意力并提升数据解读的效率。Axure&#xff0c;作为一款功能强大的原型设计工具&am…

supervision - 好用的计算机视觉 AI 工具库

Supervision库是一款出色的Python计算机视觉低代码工具&#xff0c;其设计初衷在于为用户提供一个便捷且高效的接口&#xff0c;用以处理数据集以及直观地展示检测结果。简化了对象检测、分类、标注、跟踪等计算机视觉的开发流程。开发者仅需加载数据集和模型&#xff0c;就能轻…