Qt扫盲- Graphics View框架理论综述

Graphics View框架理论综述

  • 一、概述
  • 二、Graphics View 体系结构
    • 1. The Scene
    • 2. The View
    • 3. 图元 Item
  • 三、图形视图坐标系统
    • 1. 图元Item的坐标
    • 2. Scene Scene坐标
    • 3. View 视图坐标
    • 4. 坐标映射
  • 四、关键特性
    • 1. 缩放和旋转
    • 2. 打印
    • 3. 拖放
    • 4. 鼠标指针和 提示
    • 5. 动画
    • 6. OpenGL渲染
    • 7. Item group
    • 8. 部件和布局
      • 1. QGraphicsWidget
      • 2. QGraphicsLayout
    • 9. 对嵌入Widget的支持
  • 五、性能

一、概述

Graphics View 提供了一个用于管理大量定制 2D 图形项并与之交互的表面,以及一个用于可视化这些项的视图部件,支持缩放和旋转。

该框架包括一个事件传播架构,允许Scene中的 Item 具有精确的双精度交互能力。元素可以处理按键事件、鼠标按下、移动、释放和双击事件,它们还可以跟踪鼠标移动。

Graphics View 使用BSP(二叉空间划分)树来提供非常快速的 Item 发现,因此,它可以实时可视化大型Scene,即使有数百万个 Item 。

Graphics View 在Qt 4.2中引入,取代了它的前身QCanvas。

二、Graphics View 体系结构

Graphics View 提供了一种基于项的模型视图编程方法,很像InterView的便利类QTableView, QTreeView和QListView。多个视图可以观察同一个Scene,Scene中包含不同几何形状的物品。

1. The Scene

QGraphicsScene提供Graphics View的 Scene。Scene职责如下:

  • 提供管理大量 Item 的快速界面
  • 将事件传播到每个 Item
  • 管理 Item 状态,例如选择和焦点处理
  • 提供未转换的渲染功能;主要用于 Print 功能

Scene作为QGraphicsItem对象的容器。通过调用QGraphicsScene::addItem()将物品添加到Scene中,然后通过调用众多物品发现函数中的一个来检索物品。QGraphicsScene::items()及其重载函数返回由 点、矩形、多边形或一般向量路径包含或与之相交的所有元素。QGraphicsScene::itemAt() 返回指定位置的最顶层元素所有物品发现函数都以降序堆叠的方式返回物品(即,第一个返回的物品在最上面,最后一个返回的物品在最下面)。

  QGraphicsScene scene;QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100));QGraphicsItem *item = scene.itemAt(50, 50);// item == rect

QGraphicsScene的事件传播架构调度Scene的事件以交付到 Item ,并管理 Item 之间的传播。如果Scene在某个位置接收到鼠标按下事件,则Scene会将事件传递给位于该位置的任何元素。

QGraphicsScene还管理某些 Item 状态,例如 Item 选择和焦点。你可以通过调用QGraphicsScene::setSelectionArea()来选择Scene中的元素,传入一个任意形状的参数。此功能也用作QGraphicsView中橡皮筋选择的基础。要取得当前所有选中项的列表,调用QGraphicsScene::selectedItems()。QGraphicsScene处理的另一个状态是 Item 是否具有键盘输入焦点。我们可以通过调用QGraphicsScene::setFocusItem()或QGraphicsItem::setFocus()来设置项上的焦点,或者通过调用QGraphicsScene::focusItem()来获取当前的焦点项。

最后,QGraphicsScene允许我们通过QGraphicsScene::render()函数将Scene的部分渲染到绘图设备中。

这就给我们提供了输出成图片提供了依据。

2. The View

QGraphicsView 提供了view控件,它可以可视化Scene的内容。你可以为同一个Scene添加多个视图,从而为同一个数据集提供多个视口。view部件是一个滚动区域,提供了在大型Scene中导航的滚动条。要启用OpenGL支持,可以调用QGraphicsView::setViewport()将QGLWidget设置为视图。

  QGraphicsScene scene;myPopulateScene(&scene);QGraphicsView view(&scene);view.show();

View 接收来自键盘和鼠标的输入事件,并将这些事件转换为Scene事件(将使用的坐标转换为Scene坐标),然后将事件发送到可视化Scene。

使用它的转换矩阵 QGraphicsView::transform(),视图可以转换Scene的坐标系统。视图还允许高级导航功能,如缩放和旋转。为了方便,QGraphicsView 还提供了在视图和Scene坐标之间进行转换的函数:QGraphicsView::mapToScene() 和 QGraphicsView::mapFromScene()。
在这里插入图片描述

3. 图元 Item

QGraphicsItem 是Scene中图形元素的基类。图形视图为常用的形状提供了一些标准项,例如矩形(QGraphicsItem)、椭圆(QGraphicsEllipseItem) 和文本项 (QGraphicsTextItem),但在编写自定义项时,我们可以使用最强大的 QGraphicsItem 功能。就是继承这个功能。

QGraphicsItem 支持以下特性:

  • 鼠标按下、移动、释放和双击事件,以及鼠标悬停事件、滚轮事件和上下文菜单事件。
  • 键盘输入焦点和按键事件
  • 拖放 Drop 和 Drag
  • 分组管理,有父子关系,也有QGraphicsItemGroup 分组方式
  • 碰撞检测

Items 存在于一个局部坐标系中,像 QGraphicsView 一样,它也提供了许多函数来映射物品和Scene之间的坐标,以及物品到物品之间的坐标。而且,像 QGraphicsView 一样,它可以使用矩阵 QGraphicsItem::transform() 转换其坐标系统。这对于旋转和缩放单个元素非常有用。

Items 可以包含其他Item(子Item)。父项的变换会被其所有的子项继承。然而,不管元素的累积变换如何,它的所有函数(例如QGraphicsItem::contains()、QGraphicsItem::boundingRect()、QGraphicsItem::collidesWith())仍然在局部坐标中操作。

QGraphicsItem通过QGraphicsItem::shape()函数和QGraphicsItem::collidesWith()函数支持碰撞检测,这两个函数都是虚函数。通过从QGraphicsItem::shape()返回 Item 的形状作为局部坐标QPainterPath, QGraphicsItem将为你处理所有碰撞检测。但是,如果你想提供自己的碰撞检测,可以重新实现QGraphicsItem::collidesWith()。

在这里插入图片描述

三、图形视图坐标系统

图形视图基于笛卡儿坐标系: Item 在Scene中的位置和几何形状由两组数字表示:x坐标和y坐标。当使用未变换的视图观察Scene时,Scene中的一个单位由屏幕上的一个像素表示。

注意:由于图形视图使用Qt的坐标系统,因此不支持反向y轴坐标系统(y向上增长)。

在图形视图中有三个有效的坐标系统:Item 坐标、Scene坐标和视图坐标。为了简化实现,Graphics View提供了方便的函数,允许你在三个坐标系统之间进行映射。

渲染时,图形视图的Scene坐标对应于QPainter的逻辑坐标,视图坐标与设备坐标相同。在坐标系统文档中,我们可以阅读有关逻辑坐标和设备坐标之间的关系。

在这里插入图片描述

1. 图元Item的坐标

元素存在于自己的局部坐标系统中。它们的坐标通常以中心点(0,0)为中心,这也是所有变换的中心。物品坐标系中的几何基元通常被称为物品点、物品线或物品矩形。

创建自定义item时,item的坐标是你需要担心的;QGraphicsScene和QGraphicsView将为我们执行所有转换。这使得实现自定义项非常容易。例如,如果你收到了一个鼠标按下或拖动进入事件,事件的位置会在元素的坐标中给出。

QGraphicsItem::contains()虚函数,如果某个点在 Item 内部,则返回true,否则返回false,它接受 Item 坐标中的point参数。类似地, Item 的边界矩形和形状是在 Item 的坐标中。

At item的位置是item在其父坐标系中的中心点的坐标;有时也被称为父坐标。在这个意义上,Scene被视为所有无父项的“父”。顶级物品的位置在Scene坐标中。

子元素坐标是相对于父元素坐标的。如果子元素未进行转换,则子元素坐标与父元素坐标之间的差值与父元素坐标中 Item 之间的距离相同。例如:如果一个未变换的子项精确地定位在父项的中心点上,那么两个子项的坐标系统将是相同的。如果子节点的位置是(10,0),那么子节点的(0,10)点将对应于父节点的(10,10)点。

因为元素的位置和变换是相对于父元素的,所以子元素的坐标不受父元素变换的影响,尽管父元素的变换会隐式地变换子元素。在上面的例子中,即使父元素被旋转和缩放,子元素的(0,10)点仍然对应于父元素的(10,10)点。然而,相对于Scene,子元素会跟随父元素的变换和位置。如果父元素被缩放(2x, 2x),子元素的位置将在Scene坐标(20,0)处,而它的(10,0)点将对应于Scene中的(40,0)点。

QGraphicsItem::pos()是少数例外之一,QGraphicsItem的函数在物品坐标中操作,无论物品是什么,也不管它的父元素是什么变换。例如,一个 Item 的边界矩形(即QGraphicsItem::boundingRect())总是以 Item 的坐标给出。

2. Scene Scene坐标

Scene代表所有 Item 的基础坐标系统。Scene坐标系统描述了每个顶层 Item 的位置,同时也构成了从视图发送到Scene的所有Scene事件的基础。Scene中的每个 Item 都有一个Scene位置和边界矩形(QGraphicsItem::scenePos(), QGraphicsItem::sceneBoundingRect()),除了它的局部 Item 位置和边界矩形。Scene位置描述了 Item 在Scene坐标中的位置,它的Scene边界矩形构成了QGraphicsScene如何确定Scene的哪些区域发生了变化的基础。Scene的变化通过QGraphicsScene::changed()信号传达,参数是Scene矩形的列表。

3. View 视图坐标

视图坐标是控件的坐标。视图坐标中的每个单位对应一个像素。这个坐标系统的特别之处在于它是相对于widget(或视口)的,不受观察到的Scene的影响。QGraphicsView的视口左上角始终是(0,0),右下角始终是(视口宽度,视口高度)。所有的鼠标事件和拖放事件最初都是以视图坐标的形式接收的,你需要将这些坐标映射到Scene中才能与元素进行交互。

4. 坐标映射

通常在处理Scene中的物品时,将坐标和任意形状从Scene映射到一个物品,从一个物品映射到另一个物品,或者从视图映射到Scene,都是很有用的。例如,当你在QGraphicsView的视口中点击鼠标时,你可以通过调用QGraphicsView::mapToScene()来询问Scene光标下方是什么 Item ,接下来是QGraphicsScene::itemAt()。如果你想知道 Item 在视口中的位置,可以在 Item 上调用QGraphicsItem::mapToScene(),然后在视图上调用QGraphicsView::mapFromScene()。最后,如果你想找到视图椭圆内的 Item ,可以将QPainterPath传递给mapToScene(),然后将映射的路径传递给QGraphicsScene::items()。

通过调用QGraphicsItem::mapToScene()和QGraphicsItem::mapFromScene(),可以将坐标和形状映射到物品的Scene中。你也可以通过调用QGraphicsItem::mapToParent()和QGraphicsItem::mapFromParent()映射到一个 Item 的父 Item ,或者通过调用QGraphicsItem::mapToItem()和QGraphicsItem::mapFromItem()在 Item 之间映射。所有的映射函数都可以同时映射点、矩形、多边形和路径。

在视图中也有相同的映射函数,用于与Scene的映射。QGraphicsView::mapFromScene()和QGraphicsView::mapToScene()。要从视图映射到物品,首先要映射到Scene,然后再从Scene映射到物品。

四、关键特性

1. 缩放和旋转

QGraphicsView通过QGraphicsView::setMatrix()支持与QPainter相同的仿射变换。通过对视图应用转换,我们可以轻松地添加对常见导航特性的支持,例如缩放和旋转。
下面是一个如何在QGraphicsView的子类中实现缩放和旋转槽的示例:

  class View : public QGraphicsView{Q_OBJECT...public slots:void zoomIn() { scale(1.2, 1.2); }void zoomOut() { scale(1 / 1.2, 1 / 1.2); }void rotateLeft() { rotate(-10); }void rotateRight() { rotate(10); }...};

槽函数可以连接到启用autoRepeat的QToolButtons。

当你转换视图时,QGraphicsView保持视图中心对齐。

2. 打印

图形视图通过其渲染函数QGraphicsScene::render()和QGraphicsView::render()提供单行打印。这些函数提供了相同的API:你可以通过将QPainter传递给任意一个渲染函数,让Scene或视图将它们的全部或部分内容渲染到任何绘制设备中。这个例子展示了如何使用QPrinter将整个Scene打印到一个完整的页面中。

  QGraphicsScene scene;scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green));QPrinter printer;if (QPrintDialog(&printer).exec() == QDialog::Accepted) {QPainter painter(&printer);painter.setRenderHint(QPainter::Antialiasing);scene.render(&painter);}

Scene和视图渲染函数之间的区别是一个在Scene坐标中操作,另一个在视图坐标中操作。QGraphicsScene::render()通常用于未变换地打印Scene的整个片段,例如绘制几何数据或打印文本文档。另一方面,QGraphicsView::render()适合截屏;它的默认行为是使用提供的painter渲染这个控件窗口外面的内容。

  QGraphicsScene scene;scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green));QPixmap pixmap;QPainter painter(&pixmap);painter.setRenderHint(QPainter::Antialiasing);scene.render(&painter);painter.end();pixmap.save("scene.png");

当源区域和目标区域大小不匹配时,源区域内容被拉伸以适应目标区域。通过向你正在使用的渲染函数传递Qt::AspectRatioMode,你可以选择在内容拉伸时保持或忽略Scene的纵横比。

3. 拖放

因为QGraphicsView间接地继承了QWidget,它已经提供了QWidget提供的相同的拖放功能。此外,为了方便,图形视图框架提供了对Scene和每个 Item 的拖放支持。当视图接收到拖动时,它将拖放事件转换为QGraphicsSceneDragDropEvent,然后将其转发到Scene。Scene接管了这个事件的调度,并将其发送给鼠标光标下接受drop的第一个 Item 。

要从一个元素开始拖动,创建一个QDrag对象,向开始拖动的部件传递一个指针。多个视图可以同时观察 Item ,但只有一个视图可以启动拖动。在大多数情况下,拖动是从按下或移动鼠标开始的,因此在mousePressEvent()或mouseMoveEvent()中,可以从事件中获得widget的初始指针。例如:

  void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event){QMimeData *data = new QMimeData;data->setColor(Qt::green);QDrag *drag = new QDrag(event->widget());drag->setMimeData(data);drag->start();}

为了拦截Scene的拖放事件,我们需要在QGraphicsItem子类中重新实现QGraphicsScene::dragEnterEvent()和特定Scene需要的任何事件处理程序。我们可以在每个QGraphicsScene的事件处理程序的文档中阅读有关拖放图形视图的更多信息。

Item 可以通过调用QGraphicsItem::setAcceptDrops()来启用拖放支持。要处理传入的拖动,请重新实现QGraphicsItem::dragEnterEvent()、QGraphicsItem::dragMoveEvent()、QGraphicsItem::dragLeaveEvent()和QGraphicsItem::dropEvent()。

4. 鼠标指针和 提示

与QWidget类似,QGraphicsItem也支持鼠标(QGraphicsItem::setCursor())和ToolTip (QGraphicsItem::setToolTip())。当鼠标光标进入物品区域(通过调用QGraphicsItem::contains()检测到)时,QGraphicsView会激活鼠标指针和ToolTip。
你也可以通过调用QGraphicsView::setCursor()直接在视图上设置默认鼠标指针。

5. 动画

图形视图支持多个级别的动画。你可以通过使用动画框架轻松地组装动画。为此,我们需要我们的 Item 继承QGraphicsObject并将QPropertyAnimation与它们关联。QPropertyAnimation允许对任何QObject属性进行动画。
另一种选择是创建一个自定义项,它继承自QObject和QGraphicsItem。该 Item 可以设置自己的定时器,并在QObject::timerEvent()中以增量步骤控制动画。

第三种选择是通过调用QGraphicsScene::advance()来推进Scene,它又会调用QGraphicsItem::advance(),这主要是为了在Qt 3中与QCanvas兼容。

6. OpenGL渲染

要启用OpenGL渲染,只需通过调用QGraphicsView::setViewport()设置一个新的QGLWidget作为QGraphicsView的视口。如果你想要OpenGL抗锯齿,你需要OpenGL样本缓冲支持(参见QGLFormat::sampleBuffers())。

  QGraphicsView view(&scene);view.setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));

7. Item group

通过将一项作为另一项的子元素,可以实现项分组最基本的特性:所有项都在一起移动,所有变换都可以从父元素传播到子元素。

此外,QGraphicsItemGroup是一个特殊项,它将子事件处理与用于向组中添加和从组中删除项的有用接口结合在一起。将一个元素添加到QGraphicsItemGroup将保持元素的原始位置和变换,而重新排列元素通常会导致子元素相对于新的父元素重新定位。为了方便,你可以通过Scene调用QGraphicsScene::createItemGroup()来创建QGraphicsItemGroups。

8. 部件和布局

Qt 4.4通过qgraphicwidget引入了对几何和布局感知 Item 的支持。这个特殊的基础项类似于QWidget,但与QWidget不同的是,它不是继承自QPaintDevice;而不是来自QGraphicsItem。这允许我们编写具有事件、信号和槽函数、大小提示和策略的完整窗口组件,我们还可以通过QGraphicsLinearLayout和QGraphicsGridLayout在布局中管理窗口组件的几何形状。

1. QGraphicsWidget

基于QGraphicsItem的功能和精简功能,QGraphicsWidget提供了两者的精华:来自QWidget的额外功能,如样式、字体、调色板、布局方向及其几何形状,以及来自QGraphicsItem的分辨率独立性和转换支持。因为图形视图使用真实坐标而不是整数,所以QGraphicsWidget的几何函数也可以操作QRectF和QPointF。这也适用于frame rects、margin和spacing。例如,使用QGraphicsWidget时,将内容边距指定为(0.5,0.5,0.5,0.5)是很常见的。既可以创建子窗口组件,也可以创建“顶级”窗口;在某些情况下,我们现在可以为高级MDI应用程序使用图形视图。

支持QWidget的一些属性,包括窗口标志和属性,但不是全部。我们应该参考qgraphicwidget的类文档,以获得支持什么和不支持什么的完整概述。例如,你可以通过传递Qt::Window窗口标志给qgraphicwidget的构造函数来创建装饰窗口,但是图形视图目前不支持macOS上常见的Qt::Sheet和Qt::Drawer标志。

2. QGraphicsLayout

QGraphicsLayout是专门为qgraphicwidget设计的第二代布局框架的一部分。它的API与QLayout非常相似。你可以在QGraphicsLinearLayout和QGraphicsGridLayout中管理部件和子布局。你也可以通过自己继承QGraphicsLaytItem来轻松编写自己的布局,或者通过编写QGraphicsLayoutItem的适配器子类来将自己的QGraphicsItem Item 添加到布局中。

9. 对嵌入Widget的支持

图形视图为将任何控件嵌入Scene提供无缝支持。可以嵌入简单的控件(如QLineEdit或QPushButton),复杂的控件(如QTabWidget),甚至是完整的主窗口。要将控件嵌入到Scene中,只需调用QGraphicsScene::addWidget(),或创建一个QGraphicsProxyWidget 实例来手动嵌入控件。

通过QGraphicsProxyWidget, Graphics View能够深度集成客户端widget功能,包括其光标,ToolTip,鼠标,平板电脑和键盘事件,子widget,动画,弹出窗口(例如,QComboBox或QCompleter),以及widget的输入焦点和激活。QGraphicsProxyWidget甚至集成了嵌入式widget的选项卡顺序,以便我们可以用选项卡进出嵌入式widget。我们甚至可以将新的QGraphicsView嵌入到我们的Scene中,以提供复杂的嵌套Scene。

在转换嵌入式控件时,Graphics View确保控件独立转换分辨率,允许字体和样式在放大时保持清晰。(注意,分辨率独立性的效果取决于样式。)

五、性能

为了准确、快速地为元素应用变换和特效,图形视图的构建假设用户的硬件能够为浮点指令提供合理的性能。
许多工作站和桌面计算机都配备了适当的硬件来加速这种计算,但一些嵌入式设备可能只提供处理数学运算或在软件中模拟浮点指令的库。

因此,在某些设备上,某些类型的效果可能比预期的要慢。可以通过在其他方面进行优化来弥补这种性能损失;例如,通过使用OpenGL渲染一个Scene。但是,如果这种优化本身也依赖于浮点硬件,那么性能就会下降。

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

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

相关文章

【手写数据库toadb 造不一样的轮子】行列混合存储模型 就是为大模型分析准备的

行列混合存储模型 ​专栏内容: postgresql内核源码分析手写数据库toadb并发编程个人主页:我的主页 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 概述 混合模型的由来 我们虽然造轮子,但是也会造完全一样的轮子。所以toadb在选择存储模型时,行存模型已经成熟…

Day978.如何在移动App中使用OAuth 2.0? -OAuth 2.0

如何在移动App中使用OAuth 2.0? Hi,我是阿昌,今天学习记录的是关于如何在移动App中使用OAuth 2.0?的内容。 除了 Web 应用外,现实环境中还有非常多的移动 App。 那么,在移动 App 中,能不能使…

STM32 CubeMX (第一步Freertos任务管理:创建、删除、挂起、恢复)

STM32 CubeMX Freertos STM32 CubeMX (Freertos任务:创建、删除、挂起、恢复) STM32 CubeMX Freertos前言一、STM32 CubeMX 配置时钟树配置HAL时基选择TIM1(不要选择滴答定时器;滴答定时器留给OS系统做时基&#xff09…

6.RocketMQ之索引文件ConsumeQueue

本文着重分析为consumequeue/topic/queueId目录下的索引文件。 1.ConsumeQueueStore public class ConsumeQueueStore {protected final ConcurrentMap<String>, ConcurrentMap<Integer>, ConsumeQueueInterface>> consumeQueueTable;public boolean load(…

git权限问题解决方法Access denied fatal: Authentication failed

文章目录 遇到Access denied 的权限问题解决方法1、git的密码修改过&#xff0c;但是本地没更新。2、确定问题&#xff0c;然后增加配置① 查询用户信息②如果名称和email不对&#xff0c;设置名称&#xff1a;③ 检查ssh-add是否链接正常④ 设置不要每次都输入用户名密码 3、配…

[Mac软件]MacCleaner 3 PRO 3.2.1应用程序清理和卸载

应用介绍 MacCleaner PRO是一个应用程序包&#xff0c;将帮助您清除磁盘空间并加快Mac的速度&#xff01; MacCleaner PRO - 让您的Mac始终快速、干净和有条理。 App Cleaner & Uninstaller PRO - 完全删除未使用的应用程序并管理Mac扩展。 磁盘空间分析仪PRO-分析磁盘空…

无涯教程-Perl - setnetent函数

描述 该函数应在第一次调用getnetent之前调用。 STAYOPEN参数是可选的,在大多数系统上未使用。当getnetent()从网络数据库的下一行检索信息时,setnetent会将枚举设置(或重置)为主机条目集的开头。 语法 以下是此函数的简单语法- setnetent STAYOPEN返回值 此函数不返回任何…

基于安防监控EasyCVR视频汇聚融合技术的运输管理系统的分析

一、项目背景 近年来&#xff0c;随着物流行业迅速发展&#xff0c;物流运输费用高、运输过程不透明、货损货差率高、供应链协同能力差等问题不断涌现&#xff0c;严重影响了物流作业效率&#xff0c;市场对于运输管理数字化需求愈发迫切。当前运输行业存在的难题如下&#xf…

css学习1

1、样式定义如何显示元素。 2、样式通常保存至外部的css文件中。 3、样式可以使内容与表现分离。 4、css主要有两部分组成&#xff1a;选择器与一条或多条声明。 选择器通常为要改变的html元素&#xff0c;每条声明由一个属性和一个值组成。每个属性有一个值&#xff0c;属性…

WebStorm运行vue项目

WebStorm运行vue项目&#xff08;vue2&#xff09; 1.安装webstorm 2. 需要安装node.js 环境&#xff0c;可以去官网下载 https://nodejs.org/en 3. 安装完需要查看 按winr 输入cmd进入 输入命令node -v 和npm -v 查看&#xff0c;会出现相应的版本号,代表安装成功 vue官网安…

CF 1354 C1 C2 Polygon Embedding(求奇偶正多边形的外接最小正方形的边长)

CF 1354 C1 / C2 Polygon Embedding(求奇偶正多边形的外接最小正方形的边长) Problem - C1 - Codeforces Problem - C2 - Codeforces EASY &#xff1a; 大意&#xff1a;给出一个偶数 n &#xff0c; 求 正 (2 * n) 边形的最小外接正方形的边长。 可以想出两种最直观的情况…

Qt扫盲-Qt Paint System 概述

Qt Paint System 概述 一、概述二、绘图设备和后端1. Widget2. Image3. Pixmap4. OpenGL绘制设备5. Picture6. 自定义绘制后端 三、绘图与填充1. Drawing2. 填充 Filling 四、坐标系统1. 渲染Window-Viewport转换 五、读写图像文件1. QMovie 六、绘图相关设备 一、概述 Qt的pa…