[Qt5] QGraphics图形视图框架概述(Item、Scene和View)

简介: [Qt5] QGraphics图形视图框架概述(Item、Scene和View)

以将其放置在窗口上以显示QGraphicsScene,该窗口本身包含许多QGraphicsItem子类和/或窗口小部件。 与QGraphicsScene类相似,该类还提供大量函数,方法和属性来处理图形的可视化部分。 我们将审核以下列表中的一些最重要的函数,然后我们将学习如何对QGraphicsView进行子类化并将其扩展为在我们全面的计算机视觉应用中具有若干重要功能,例如放大,缩小, 项目选择等。因此,这是我们在计算机视觉项目中需要的QGraphicsView类的方法和成员:

  • alignmentsetAlignment函数可用于设置场景在视图中的对齐方式。 重要的是要注意,只有当视图可以完全显示场景,即视图不需要滚动条时,这才具有可见效果。一般当场景大于视图会出现滚动条,是不能通过setAlignment()函数来设置场景在视图中的对齐方式的。
左对齐Qt::AlignLeft ; 向上对齐Qt::AlignTop ; 中心对齐Qt::AlignCenter
eg:setAlignment(Qt::AlignLeft | Qt::AlignTop);
  • dragModesetDragMode函数可用于获取和设置视图的拖动模式。 这是视图的最重要函数之一,它可以决定在视图上单击并拖动鼠标左键时会发生什么。我们将使用QGraphicsView::DragMode枚举设置不同的拖动模式。
QGraphicsView::NoDrag:忽略鼠标事件,不可以拖动。
QGraphicsView::ScrollHandDrag:光标变为手型,可以拖动场景进行移动。
QGraphicsView::RubberBandDrag:使用橡皮筋效果,进行区域选择,可以选中一个区域内的所有图形项。
  • isInteractivesetInteractive函数允许检索和修改视图的交互行为。 交互式视图会响应鼠标和键盘(如果已实现),否则,所有鼠标和键盘事件都将被忽略,并且该视图只能用于查看并且不能与场景中的项目进行交互。
  • optimizationFlagssetOptimizationFlagsrenderHintssetRenderHintsviewportUpdateModesetViewportUpdateMode函数分别用于获取和设置与视图的性能和渲染质量有关的参数。 在下面的示例项目中,我们将在实践中看到这些函数的用例。
  • dragMode设置为RubberBandDrag模式的情况下,可以使用rubberBandSelectionModesetRubberBandSelectionMode函数设置视图的项目选择模式。 可以设置以下内容,它们是Qt::ItemSelectionMode枚举中的条目:
Qt::ContainsItemShape、Qt::IntersectsItemShape、Qt::ContainsItemBoundingRect、Qt::IntersectsItemBoundingRect
  • sceneRectsetSceneRect函数可用于获取和设置视图中场景的可视化区域。 显然,该值不必与QGraphicsScene类的sceneRect相同。
  • centerOn函数可用于确保特定点或项目位于视图中心。
  • ensureVisible函数可用于将视图滚动到特定区域(具有给定的边距)以确保它在视图中。 此函数适用于点,矩形和图形项目。
  • fitInView函数与centerOnensureVisible非常相似,但主要区别在于,该函数还使用给定的宽高比处理参数缩放视图的内容以适合视图。 以下:
Qt::IgnoreAspectRatio、Qt::KeepAspectRatio、Qt::KeepAspectRatioByExpanding
eg:fitInView(m_view->sceneRect(), Qt::KeepAspectRatio);   //场景大小适应视图View大小
  • itemAt函数可用于在视图中的特定位置检索项目。

  我们已经了解到场景中的每个项目和场景中的每个项目都有各自的坐标系,我们需要使用映射函数将位置从一个位置转换到另一个位置,反之亦然。 视图也是如此。 视图还具有自己的坐标系,主要区别在于视图中的位置和矩形等实际上是根据像素进行测量的,因此它们是整数,但是场景和项目的位置使用实数,等等。 这是由于以下事实:场景和项目在视图上被查看之前都是逻辑实体,因此所有实数都将转换为整数,而整个场景(或部分场景)准备在屏幕上显示。下图可以帮助您更好地理解这一点:

  • mapFromScenemapToScene函数可用于在场景坐标系之间转换位置。与前面提到的一致,mapFromScene函数接受实数并返回整数值,而mapToScene函数接受整数并返回实数。稍后我们将开发视图的缩放功能时,将使用这些函数。
  • items函数可用于获取场景中的项目列表。
  • render函数对于执行整个视图或其一部分的渲染很有用。该函数的用法与QGraphicsScene中的render完全相同,只是此函数在视图上执行相同的功能。
  • rubberBandRect函数可用于获取橡皮筋选择的矩形。如前所述,这仅在拖动模式设置为rubberBandSelectionMode时才有意义。
  • setScenescene函数可用于设置和获取视图场景。
  • setMatrix,setTransform,transform,rotate,scale,shear和translate函数都可以用于修改或检索视图的几何特性。

  与QGraphicsSceneQGraphicsItem类相同,QGraphicsView还提供了许多相同的受保护虚拟成员,可用于进一步扩展视图的功能。 现在,我们将对平时应用QGraphicsView扩展类时经常使用到的功能:

1、缩放与旋转

QGraphicsView::scale(xScale, yScale);//在分别在x,y方向上缩放xScale,yScale倍。若为1.0倍,则不进行缩放。
QGraphicsView::rotate(90);//顺时针旋转90度

  功能实现:

//重写QGraphicsView类中滑轮事件,完成缩放功能。MyGraphicsView为继承QGraphicsView的子类
void MyGraphicsView::wheelEvent(QWheelEvent *event) 
{ 
  // 获取当前鼠标相对于view的位置;
  QPointF cursorPoint = event->pos();
  // 获取当前鼠标相对于scene的位置;
  QPointF scenePos = this->mapToScene(QPoint(cursorPoint.x(), cursorPoint.y()));  
  // 获取view的宽高;
  qreal viewWidth = this->viewport()->width();
  qreal viewHeight = this->viewport()->height();
  // 获取当前鼠标位置相当于view大小的横纵比例;
  qreal hScale = cursorPoint.x() / viewWidth;
  qreal vScale = cursorPoint.y() / viewHeight;
  // 当前放缩倍数;
  //qreal scaleFactor = this->matrix().m11();
  int wheelDeltaValue = event->delta();
  // 向上滚动,放大
  if (wheelDeltaValue > 0)
  {
    this->scale(1.4, 1.4);
  }
  // 向下滚动,缩小;
  else
  {
    this->scale(1/ 1.4, 1 / 1.4);;
  }   
  // 将scene坐标转换为放大缩小后的坐标;
  QPointF viewPoint = this->matrix().map(scenePos);
  // 通过滚动条控制view放大缩小后的展示scene的位置;
  this->horizontalScrollBar()->setValue(int(viewPoint.x() - viewWidth * hScale));
  this->verticalScrollBar()->setValue(int(viewPoint.y() - viewHeight * vScale));
}

2、其他事件传递

  在上面我们看到必须在事件函数的最后将event参数传递出去,才能执行默认的事件操作。其实不止上面那一种情况,在图形视图框架中,鼠标键盘等事件是从视图View进入的,视图View将它们传递给场景Scene,场景Scene再将事件传递给该点的图形项Item,如果该点有多个图形项,那么就传给最上面的图形项。所以要想使这个事件能一直传播下去,我们就需要在重新实现事件处理函数时,在其最后将event参数传给默认的事件处理函数。比如我们重写了场景的键盘按下事件处理函数,那么我们就在该函数的最后写上QGraphicsView::keyPressEvent(event);

  除了像上面那样通过直接重写QGraphicsView的虚函数的方式来实现事件的传递之外,还可以通过事件过滤器eventFilter的方式来实现:

MyGraphicsView::MyGraphicsView(QWidget *parent)
  :QGraphicsView(parent)
{
    this->viewport()->installEventFilter(this); 
}
bool MyGraphicsView::eventFilter(QObject *obj, QEvent *event)
{
    /*
    实现方式
    */
    return false;     //返回false表示不过滤
}

🌺 场景类 — QGraphicsScene

  场景分为3层:分别是背景层、图形项层、前景层。我们绘制的图形item都是放在图形项层的:

  QGraphicsScene类提供了处理多个图形项(QGraphicsItem)所需的几乎所有方法。其主要作用是作为一个容器放置图元Item,本身是不可见的,必须关联到至少一个QGraphicsView。这两者的关系就画布和画板的关系,View是画板,负责显示;Scene是画布,负责存储图形数据。所以从这个角度出发,我们可以这样认为,一个Scene可以关联到多个View,就好比一份画布贴到不同的画板上来被外界所看到一样。

  • addEllipseaddLineaddRectaddPolygon函数可以从它们的名称中猜测出来,可以用来向场景添加通用的几何形状。 它们中的一些提供了重载函数,以便于输入参数。 创建并添加到场景时,上述每个函数都会返回其对应的QGraphicsItem子类实例(如下所示)。返回的指针可以保留,以后可用于修改,删除或以其他方式使用该项目:
QGraphicsEllipseItem
QGraphicsLineItem
QGraphicsRectItem
QGraphicsPolygonItem

  使用示例:

scene.addEllipse(-100.0, 100.0, 200.0, 100.0, 
                QPen(QBrush(Qt::SolidPattern), 2.0), 
                QBrush(Qt::Dense2Pattern)); 
scene.addLine(-200.0, 200, +200, 200, 
              QPen(QBrush(Qt::SolidPattern), 5.0)); 
scene.addRect(-150, 150, 300, 140); 
QVector<QPoint> points; 
points.append(QPoint(150, 250)); 
points.append(QPoint(250, 250)); 
points.append(QPoint(165, 280)); 
points.append(QPoint(150, 250)); 
scene.addPolygon(QPolygon(points));

  代码结果:

  • addPath函数可用于将QPainterPath与给定的QPenQBrush添加到场景中。QPainterPath类可用于记录绘画操作,类似于我们在QPainter中看到的操作,并在以后使用它们。另一方面,QPenQBrush类具有不言自明的标题。addPath函数返回一个指向新创建的QGraphicsPathItem实例的指针。
  • addSimpleTextaddText函数可用于将纯文本和带格式的文本添加到场景中。 它们分别返回指向QGraphicsSimpleTextItemQGraphicsTextItem的指针。

  使用示例:

QGraphicsScene *pScene = new QGraphicsScene();
QGraphicsView  *pView  = new QGraphicsView();
//1、将项目Item添加到场景Scene中,即构造一个QGraphicsScene的对象。
pScene->addText("Hello, world!");//添加文本图形项
//2、使用QGraphicsView::setScene()将Scene加入到View中,视图View的可视化需要场景Scene的加入来进行实现。
pView->setScene(pScene);
pView->show();

  代码结果:

  图形项Item添加到场景Scene中有两种方式,一是通过调用便利函数addEllipse()、addLine()、addPath()、addPixmap()、addPolygon()、addRect()或addText()等,这些函数都返回指向新添加项的指针。二是调用addIitem()添加现有的QGraphicsItem对象(主要是自定义继承的QGraphicsItem);使用这些函数添加的项目的尺寸是相对于项目的坐标系的,并且项目位置在场景中初始化为(0,0)

  那么,上面addText("Hello, world!") 则可以换转成方式二:通过调用addIitem()添加现有的QGraphicsItem对象:

QGraphicsTextItem *item = new QGraphicsTextItem("Hello, world!");
scene.addItem(item);
  • addWidget函数可用于将 Qt 小部件添加到场景。 除了某些特殊的小部件(即设置了Qt::WA_PaintOnScreen标志的小部件或使用外部库(例如OpenGLActive-X绘制的小部件))之外,您还可以将其他任何小部件添加到场景中,这为使用交互式图形项创建场景提供了巨大的力量。下面举一个简短的示例:将场景和QWidget窗体绑定
if (m_view == nullptr){
  m_view = new MF_GraphicsView(_parent);
}
if (m_scene == nullptr){
  m_scene = new MF_GraphicsScene();
}
m_scene->setSceneRect(m_view->pos().x(), m_view->pos().y(), 2040, 2040);   //设置场景大小 
m_view->setScene(m_scene);      //将场景绑定到视图上 
if (ui.widget->layout() == nullptr)
{
  QGridLayout* _layout = new QGridLayout();
  _layout->setMargin(0);
  ui.widget->setLayout(_layout);
}
ui.widget->layout()->addWidget(m_view);
  • setBackgroundBrushbackgroundBrushsetForegroundBrushforegroundBrush函数允许访问负责刷新场景的backgroundforegroundQBrush类。
  • fontsetFont函数可用于获取或设置QFont类,以确定场景中使用的字体。
  • 当我们想要定义最小尺寸来决定某项是否适合绘制(渲染)时,minimumRenderSizesetMinimumRenderSize函数非常有用。
  • sceneRectsetSceneRect函数可用于指定场景的边界矩形。默认情况下,场景的大小是无限的。图形项可以放到场景的任何位置。这导致场景想要搜索所有的图形项,然后确定出其边界,这是十分费时的。所以如果要操作一个较大的场景,我们应该给出它的边界矩形。设置边界矩形,可以使用setSceneRect()函数。上面Hello world例子加入场景边界矩形的方式如下:
QGraphicsView *pView = new QGraphicsView();
QGraphicsScene *pScene = new QGraphicsScene();
pScene->setSceneRect(0, 0, pView->width(), pView->height());
pScene->addText("Hello, world!");//添加文本图形项
pView->setScene(pScene);
pView->show();
  • stickyFocussetStickyFocus函数可用于启用或禁用场景的粘滞聚焦模式。 如果启用了粘滞聚焦,则单击场景中的空白区域不会对聚焦的项目产生任何影响; 否则,将仅清除焦点,并且不再选择选定的项目。
  • collidingItems是一个非常有趣的功能,可用于简单地确定某项是否与其他任何项共享其区域的某个部分(或发生碰撞)。 您需要将QGraphicsItem指针与Qt::ItemSelectionMode一起传递,您将获得与项目发生冲突的QGraphicsItem实例的QList
  • createItemGroupdestroyItemGroup函数可用于创建和删除QGraphicsItemGroup类实例。 QGraphicsItemGroup基本上是另一个QGraphicsItem子类(如QGraphicsLineItem等),可用于将一组图形项分组并因此表示为单个项。
  • hasFocus,setFocus,focusItem和setFocusItem函数均用于处理图形场景中当前聚焦的项目。
  • 返回与sceneRect.width()sceneRect.height()相同值的widthheight可用于获取场景的宽度和高度。 请务必注意,这些函数返回的值的类型为qreal(默认情况下与double相同),而不是integer,因为场景坐标在像素方面不起作用。 除非使用视图绘制场景,否则将其上的所有内容都视为逻辑和非视觉对象,而不是视觉对象,这是QGraphicsView类的领域。
  • 在某些情况下,与update()相同的invalidate可用于请求全部或部分重绘场景。 类似于刷新函数。
  • itemAt函数可用于在场景中的某个位置找到指向QGraphicItem的指针。
  • item返回添加到场景的项目列表。 基本上是QGraphicsItemQList
  • itemsBoundingRect可用于获取QRectF类,或仅获取可包含场景中所有项目的最小矩形。 如果我们需要查看所有项目或执行类似操作,此函数特别有用
  • mouseGrabberItem可用于获取当前单击的项目,而无需释放鼠标按钮。 此函数返回一个QGraphicsItem指针,使用它我们可以轻松地向场景添加“拖动和移动”或类似功能。
  • removeItem函数可用于从场景中删除项目。 此函数不会删除该项目,并且调用方负责任何必需的清理。
  • selectedItems,selectionArea和setSelectionArea函数结合使用时,可以帮助处理一个或多个项目选择。 通过提供Qt::ItemSelectionMode枚举,我们可以基于完全选择一个框中的项目或仅对其一部分进行选择,等等。 我们还可以为该函数提供Qt::ItemSelectionOperation枚举条目,以增加选择或替换所有先前选择的项目。
  • sendEvent函数可用于将QEvent类(或子类)发送到场景中的项目。
  • stylesetStyle函数用于设置和获取场景样式。
  • update函数可用于重绘部分或全部场景。 当场景的视觉部分发生变化时,最好将此函数与QGraphicsScene类发出的变化信号结合使用。
  • views函数可用于获取QList类,其中包含用于显示(或查看)此场景的QGraphicsView小部件。

   除了先前的现有方法外,QGraphicsScene提供了许多虚拟函数,可用于进一步自定义和增强QGraphicsScene类的行为以及外观。 因此,与其他任何类似的 C++ 类一样,您需要创建QGraphicsScene的子类,并只需添加这些虚拟函数的实现即可。 实际上,这是使用QGraphicsScene类的最佳方法,它为新创建的子类提供了极大的灵活性:

  • 可以覆盖dragEnterEvent,dragLeaveEvent,dragMoveEvent和dropEvent函数,以向场景添加拖放功能。 请注意,这与前面示例中将图像拖放到窗口中所做的非常相似。 这些事件中的每一个都提供足够的信息和参数来处理整个拖放过程。
  • 如果我们需要在整个场景中添加自定义背景或前景,则应覆盖drawBackgrounddrawForeground函数。 当然,对于简单的背景或前景绘画或着色任务,我们可以简单地调用setBackgroundBrushsetForegroundBrush函数,而跳过这些函数。
  • mouseDoubleClickEvent,mouseMoveEvent,mousePressEventmouseReleaseEvent和wheelEvent函数可用于处理场景中的不同鼠标事件。 例如,在项目中为场景添加放大和缩小功能时,可通过重写wheelEvent函数来实现。
  • QGraphicsScene的是从QGraphicsView传播事件。要将事件发送到场景,可以构造继承QEvent的事件,然后使用QApplication::SendEvent()发送它。event()负责将事件分派给各个项目。一些常见事件由方便的事件处理程序处理。例如,按键事件由keypressEvent()处理,鼠标按键事件由mousePressEvent()处理。

🌺 图元类 — QGraphicsItem

  它是场景中各个图元的基类,在它的基础上可以继承出各种图元类,即使您可以将其子类化并创建自己的图形项(自己重新实现绘制函数),Qt也会提供一组子类,这些子类可用于大多数(如果不是全部)日常图形任务。 以下是这些子类:

QGraphicsEllipseItem     //椭圆
QGraphicsLineItem        //直线
QGraphicsPathItem
QGraphicsPixmapItem
QGraphicsPolygonItem     //多边形
QGraphicsRectItem        //矩形
QGraphicsSimpleTextItem   
QGraphicsTextItem        //文本图元
  • QGraphicsItem主要有以下功能:
    处理鼠标按下、移动、释放、双击、悬停、滚轮和右键菜单事件。
    处理键盘输入事件。
    处理拖拽事件。
    分组。
    碰撞检测。

  如前所述,QGraphicsItem提供了许多函数和属性来处理图形应用中的问题和任务。 在本文中,我们将介绍QGraphicsItem中一些最重要的成员,这些成员因此可以通过熟悉前面提到的子类来帮助我们:

  • acceptDropssetAcceptDrops函数可用于使项目接受拖放事件。 请注意,这与我们在前面的示例中已经看到的拖放事件非常相似,但是这里的主要区别是项目本身可以识别拖放事件。
  • acceptHoverEventssetAcceptHoverEventsacceptTouchEventssetAcceptTouchEventsacceptedMouseButtonssetAcceptedMouseButtons函数均处理项目交互及其对鼠标单击的响应等。 这里要注意的重要一点是,一个项目可以根据Qt::MouseButtons枚举设置来响应或忽略不同的鼠标按钮。 这是一个简单的例子:
QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 100, 100, this); 
item->setAcceptDrops(true); 
item->setAcceptHoverEvents(true); 
item->setAcceptedMouseButtons( Qt::LeftButton | 
                               Qt::RightButton | 
                               Qt::MidButton);
  • boundingRegion函数可用于获取描述图形项区域的QRegion类。 这是一项非常重要的函数,因为它可用于获取需要绘制(或重绘)项目的确切区域,并且与项目的边界矩形不同,因为简单地说,该项目可能仅覆盖其边界矩形的一部分,如直线等。 有关更多信息,请参见以下示例。
  • 在计算项目的boundingRegion函数时,boundingRegionGranularitysetBoundingRegionGranularity函数可用于设置和获取粒度级别。 从这个意义上讲,粒度是0和1之间的实数,它对应于计算时的预期详细程度:
QGraphicsEllipseItem *item = new QGraphicsEllipseItem(0, 0, 100, 100); 
scene.addItem(item); 
item->setBoundingRegionGranularity(g); // 0 , 0.1 , 0.75 and 1.0 
QTransform transform; 
QRegion region = item->boundingRegion(transform); 
QPainterPath painterPath; 
painterPath.addRegion(region); 
QGraphicsPathItem *path = new QGraphicsPathItem(painterPath); 
scene.addItem(path);

  在前面的代码中,如果将g替换为0.0,0.1,0.75和1.0,则会得到以下结果。 显然,0的值(默认粒度)导致单个矩形(边界矩形),这不是准确的估计。 随着级别的增加,我们得到了覆盖图形形状和项目的更准确的区域(基本上是矩形集):

  • childItems函数可用于获取填充有QGraphicsItem类的QList,这些类是此项的子级。 将它们视为更复杂项目的子项目。
  • childrenBoundingRectboundingRectsceneBoundingRect函数可用于检索QRectF类,其中包含该项目的子项bounding rect,该项目本身和场景。
  • clearFocussetFocushasFocus函数可用于删除,设置和获取该项目的聚焦状态。 具有焦点的项目接收键盘事件。
  • collidesWithItemcollidesWithPathcollidingItems函数可用于检查此项目是否与任何给定项目发生冲突,以及该项目与之碰撞的项目列表。
  • contains函数获取一个点的位置(准确地说是QPointF类),然后检查此项是否包含该点。
  • cursorsetCursorunsetCursorhasCursor函数对于设置,获取和取消设置此项的特定鼠标光标类型很有用。 您还可以在取消设置之前检查项目是否有任何设置的光标。 设置后,如果鼠标光标悬停在该项目上,则光标形状变为一组。
  • hideshowsetVisibleisVisibleopacitysetOpacityeffectiveOpacity函数均与商品的可见性(和不透明度)有关。 所有这些函数都具有不言自明的名称,唯一值得注意的是effectiveOpacity,它可能与此项的不透明度相同,因为它是基于该项及其父项的不透明度级别计算的。 最终,effectiveOpacity是用于在屏幕上绘制该项目的不透明度级别。
  • flagssetFlagssetFlag函数可用于获取或设置此项的标志。 通过标志,我们基本上是指QGraphicsItem::GraphicsItemFlag枚举中各项的组合。 这是一个示例代码:
item->setFlag(QGraphicsItem::ItemIsFocusable, true); 
item->setFlag(QGraphicsItem::ItemIsMovable, false);

  重要的是要注意,当我们使用setFlag函数时,所有以前的标志状态都会保留,并且此函数中只有一个标志会受到影响。 但是,当我们使用setFlags时,基本上所有标志都会根据给定的标志组合进行重置。

  • 当我们想要更改从场景中获取鼠标和键盘事件的项目时,grabMouse,grabKeyboardungrabMouseungrabKeyboard方法很有用。 显然,使用默认实现时,一次只能抓取一个项目,除非另一个抓取项目或者项目本身不变形或被删除或隐藏,否则抓取器将保持不变。 正如本章前面所看到的,我们总是可以使用QGraphicsScene类中的mouseGrabberItem函数来获取抓取器项目。
  • setGraphicsEffectgraphicsEffect函数可用于设置和获取QGraphicsEffect类。 这是一个非常有趣且易于使用的函数,但功能强大,可用于向场景中的项目添加过滤器或效果。QGraphicsEffectQt中所有图形效果的基类。 您可以将其子类化并创建自己的图形效果或过滤器,也可以仅使用提供的Qt图形效果之一。 目前,Qt中有一些图形效果类,您可以自己尝试一下:
QGraphicsBlurEffect
QGraphicsColorizeEffect
QGraphicsDropShadowEffect
QGraphicsOpacityEffect

  现在,让我们继续进行QGraphicsItem类中的其余函数和属性:

  • 当我们想将一个项目添加到组中或获取包含该项目的组类时,groupsetGroup函数非常有用,只要该项目属于任何组。 QGraphicsItemGroup是负责处理组的类。
  • isAncestorOf函数可用于检查该项目是否为任何给定其他项目的父项(或父项的父项,依此类推)。
  • 可以设置setParentItemparentItem并检索当前项目的父项目。 一个项目可能根本没有任何父项,在这种情况下,parentItem函数将返回零。
  • isSelectedsetSelected函数可用于更改项目的所选模式。 这些函数与setSelectionArea和您在QGraphicsScene类中了解的类似函数密切相关。
  • mapFromItemmapToItemmapFromParentmapToParentmapFromScenemapToScenemapRectFromItemmapRectToScenemapRectFromParentmapRectToParentmapRectFromScenemapRectToScene函数 ,所有这些函数甚至都具有更多方便的重载函数,构成了一长串函数,这些函数用于从或向其进行基本映射,或者换句话说,可用于从场景,另一项或父对象到场景的坐标转换。

  与我们在QGraphicsScene类中看到的类似,QGraphicsItem类还包含许多受保护的虚函数,这些函数可以重新实现,主要用于处理传递到场景项上的各种事件。 以下是一些重要且非常有用的示例:

contextMenuEvent
dragEnterEvent,dragLeaveEvent,dragMoveEvent,dropEvent
focusInEvent,focusOutEvent
hoverEnterEvent,hoverLeaveEvent,hoverMoveEvent
keyPressEvent,keyReleaseEvent
mouseDoubleClickEvent,mouseMoveEvent,mousePressEvent,mouseReleaseEvent,wheelEvent

📃 总结

   QGraphicsView的作用相当于画板QGraphicsScene等效于画布QGraphicsItem为画布上的画

   映射到Qt中就是:

  • 拿出画板,订上一张画布:UI中添加了一个QGraphicsView后,需要往其中添加QGraphicsScene,可以添加好几张画布;
  • 拿起笔,在画布上作画:往QGraphicsScene上添加各式各样的QGraphicsItemQGraphicsItem有很多种,最常用的是QGraphicsPixmapItem,也就是贴图到画布上;使用QPainter,可以自己亲自画线。

   大致过程就如上所述,因此,完成一幅图片的显示需要三个步骤:

  1. Pixmap添加至QGraphicsPixmapItem
  2. QGraphicsPixmapItem添加至QGraphicsScene
  3. QGraphicsScene添加至QGraphicsView

戳戳小手帮忙点个免费的赞和关注吧,嘿嘿。


目录
相关文章
|
3月前
|
算法 计算机视觉
基于qt的opencv实时图像处理框架FastCvLearn实战
本文介绍了一个基于Qt的OpenCV实时图像处理框架FastCvLearn,通过手撕代码的方式详细讲解了如何实现实时人脸马赛克等功能,并提供了结果展示和基础知识回顾。
111 7
基于qt的opencv实时图像处理框架FastCvLearn实战
|
3月前
|
文字识别 计算机视觉 开发者
基于QT的OCR和opencv融合框架FastOCRLearn实战
本文介绍了在Qt环境下结合OpenCV库构建OCR识别系统的实战方法,通过FastOCRLearn项目,读者可以学习Tesseract OCR的编译配置和在Windows平台下的实践步骤,文章提供了技术资源链接,帮助开发者理解并实现OCR技术。
144 9
基于QT的OCR和opencv融合框架FastOCRLearn实战
WK
|
20天前
|
开发框架 开发工具 C++
C++跨平台框架Qt
Qt是一个功能强大的C++跨平台应用程序开发框架,支持Windows、macOS、Linux、Android和iOS等操作系统。它提供了250多个C++类,涵盖GUI设计、数据库操作、网络编程等功能。Qt的核心特点是跨平台性、丰富的类库、信号与槽机制,以及良好的文档和社区支持。Qt Creator是其官方IDE,提供了一整套开发工具,方便创建、编译、调试和运行应用程序。Qt适用于桌面、嵌入式和移动应用开发。
WK
51 5
|
3月前
|
C语言 C++ Windows
QT多插件通信框架CTK编译记录
本文记录了编译QT多插件通信框架CTK的过程,包括编译结果截图、部署配置、Log4Qt编译配置、参考链接和拓展资料。文中提供了详细的编译步骤和配置文件示例,以及相关的资源链接。
QT多插件通信框架CTK编译记录
|
5月前
|
数据安全/隐私保护 C++ 计算机视觉
Qt(C++)开发一款图片防盗用水印制作小工具
文本水印是一种常用的防盗用手段,可以将文本信息嵌入到图片、视频等文件中,用于识别和证明文件的版权归属。在数字化和网络化的时代,大量的原创作品容易被不法分子盗用或侵犯版权,因此加入文本水印成为了保护原创作品和维护知识产权的必要手段。 通常情况下,文本水印可以包含版权声明、制作者姓名、日期、网址等信息,以帮助识别文件的来源和版权归属。同时,为了增强防盗用效果,文本水印通常会采用字体、颜色、角度等多种组合方式,使得水印难以被删除或篡改,有效地降低了盗用意愿和风险。 开发人员可以使用图像处理技术和编程语言实现文本水印的功能,例如使用Qt的QPainter类进行文本绘制操作,将文本信息嵌入到图片中,
187 1
Qt(C++)开发一款图片防盗用水印制作小工具
|
4月前
|
监控 C++ 容器
【qt】MDI多文档界面开发
【qt】MDI多文档界面开发
94 0
|
3月前
|
开发工具 C++
qt开发技巧与三个问题点
本文介绍了三个Qt开发中的常见问题及其解决方法,并提供了一些实用的开发技巧。
|
3月前
|
4月前
|
C++
C++ Qt开发:QUdpSocket网络通信组件
QUdpSocket是Qt网络编程中一个非常有用的组件,它提供了在UDP协议下进行数据发送和接收的能力。通过简单的方法和信号,可以轻松实现基于UDP的网络通信。不过,需要注意的是,UDP协议本身不保证数据的可靠传输,因此在使用QUdpSocket时,可能需要在应用层实现一些机制来保证数据的完整性和顺序,或者选择在适用的场景下使用UDP协议。
172 2
Qt开发网络嗅探器02
Qt开发网络嗅探器02