zoukankan      html  css  js  c++  java
  • Graphics View框架

     

    Qt4.2开始引入了Graphics View框架用来取代Qt3中的Canvas模块,并在很多地方作了改进,Graphics View框架实现了模型-视图结构的图形管理,能对大量图元进行管理,支持碰撞检测,坐标变换和图元组等多种方便的功能。GraphicsView中增强的表现系统可以利用Qt4绘图系统的反锯齿,OpenGL工具来改善绘图性能,Graphics View支持事件传播体系结构,可以利用图元在场景(scene)中的到提高了一倍的精确交互能力,图元能够处理键盘事件,鼠标按下,移动,释放,双击事件,也能跟踪鼠标的移动,在Graphics View框架中,通过BSP(二元空间划分树)来提供快速的图元查找.这样就能实时地显示大场景,甚至上百万个图元。GraphicsView框架提供基于图元的视图-模型编程,类似于QtInterView的模型,视图结构,只是这里的数据是图形,Graphics View框架中包含三个主要的类,QGraphicsScene,QGraphicsView,QGraphicsItem,分别是场景,视图和图元。一个场景可以通过多个视图表现,一个场景中包括多个几何图形。 
    --------------------------- 
    1 场景QGraphicsScene 
    QGraphicsScene类实现QGraphics View中的场景,场景类完成如下功能: 
    提供管理大量图元的快速接口 
    传播事件给场景中的每个图元 
    管理图元状态,如选择焦点处理 
    提供无变换的绘制功能,如打印 
    场景是QGraphicsItem对象的容器,通过函数QGraphicsScene::addItem()可以加入一个图元到场景中,图元可以通过多个函数进行检索,QGraphicsScene::items()和一些重载的函数可以返回点,矩形,多边形或向量路径相交的所有图元,QGraphicsScene::itemAt()返回指定点的顶层图元。QGraphicsScene的事件传播体系结构将场景事件发送给图元,同时也管理图元之间的事件传播,如果场景收到了某一点的鼠标单击事件,场景会把事件传给在这一点的图元。QGraphicsScene负责管理一些图元的状态,如图元选择和焦点。可以通过QGraphicsScene::setSeletionArea()函数选择图元,选择区域可以是任意的形状,使用QPainterPath表示,要得到当前选择的图元列表可以使用QGraphicsScene::selectedItems().QGraphicsScene还管理图元的键盘输入焦点状态,可以通过QGraphicsScene::setFocusItem()函数或者QGraphicsItem::setFoucs()函数来设置图元的焦点,获得当前具有焦点的图元使用函数QGraphicsScene::foucsItem().如果需要在场景内绘制到特定的绘图设备,可以使用QGraphicsScene::render()函数在绘图设备上绘制场景。 
    2 视图 
    QGraphics View是视图窗口部件,他使场景内容可视化,可以连接几个视图到一个场景,也可以为相同的数据源的数据集提供集中不同的视口。QGraphicsView是可滚动的窗口部件,可以提供滚动条来浏览大的场景。如果需要使用OpenGL,可以使用QGraphicsView::setViewport()将适口设置为QGLWidget.视图接收键盘和鼠标的输入事件,并把它翻译为场景事件。(将坐标转换为场景的坐标)。使用变换矩阵函数QGraphicsView::martix可以变换场景的坐标。通过这种方法可以实现场景的缩放和旋转。QGraphicsView提供QGraphicsView::mapToScene()和QGraphicsView::mapFromScene()来和场景的坐标进行转换。 
    3 图元 
    QGraphicsItem是图元的基类。QGraphics View框架提供了几种标准的图元。矩形(QGraphicsRectItem),椭圆(QGraphcisEllipseItem),文本图元(QGraphicsTextItem)等。用户可以继承QGraphicItem实现符合自己的图元。QGraphicsItem具有下列功能: 
    处理鼠标按下,移动,释放,双击,悬停,滚动和右键菜单事件。 
    处理键盘输入事件 
    处理拖放事件  分组:  碰撞检测 
    图元有自己的坐标系统,也提供场景和图元。图元和图元之间的坐标变换函数,图元也可以通过QGraphicsItem::martix()来进行自身的变换。图元可以包含子图元。
      ---------------------------------------------------------------------- 
    Graphics View坐标系统 
    Graphics View坐标系基于笛卡尔坐标系,一个图元的场景坐标具有x坐标和y坐标。当使用没有变换的视图观察场景时,场景中的一个单元对应屏幕上的一个像素。在Graphics View中有三个有效的坐标系统,图元坐标,场景坐标,和视图坐标。Graphics View提供了三个坐标系统之间的转换函数。在绘制图形所时,QGraphics View的场景坐标对应QPainter的逻辑坐标,视图坐标和设备坐标相同。 
    1 图元坐标 
    图元使用自己的本地坐标,这个坐标系统通常以图元中心为原点,这也是所有坐标变换的原点,图元坐标方向是x轴正方向向右。y轴正方向下。创建图元后,之需要注意图元的坐标就可以了。QGraphicsScene和QGraphicsView会完成所有的变换。
    2 场景坐标 
    场景坐标是所有图元的基础坐标系统。场景坐标系统描述了顶层图元。每个图元都有场景坐标和相应的包容框,场景坐标的原点在场景中心. 
    3 视图坐标 
    视图坐标是窗口部件的坐标,视图坐标的单位是像素,QGraphicsView的左上角是(0,0).所有鼠标事件最开始都使用视图坐标。 
    4 坐标映射 
    在Graphics View框架中,经常需要将多种坐标变换,从场景到图元,从图元到图元,从视图到场景  QGraphics View框架坐标变换函数 
    -------------------------------------------------- ----------------------- 
    QGraphicsView::mapToScene() 
    QGraphicsView::mapFromScene() 
    QGraphicsItem::mapFromScene() 
    QGraphicsItem::mapToScene() 
    QGraphicsItem::mapToParent() 
    QGraphicsItem::mapFromParent(); 
    QGraphicsItem::mapToItem(); 
    QGraphicsItem::mapFromItem(); 
    -------------------------------------------------- ----------------------- 
    深入 QGraphics View 
    1 缩放和旋转 
    GraphicsView通过QGraphicsView::setMartix()支持同QPainter一样的几何变换。当进行视图变换时,QGraphicsView保持视图中心。通过应用变换,可以很容易实现缩放和旋转。  下面说明如何通过缩放和旋转槽来实现对视图的缩放和旋转。 
    class View::public QGraphicsView  { 
    Q_OBJECT  ..... 
    public slots: 
    void zoomIn(){scale(1.5,1.5);}; 
    void zoomOut(){scale(1/1.5,1/1.5);} 
    void rotateLeft(){rotate(-90);} 
    void rotateRight(rotate(90);)  ....  }; 
    将槽和具有autoRepeat属性的QToolButton进行连接,就可以实现连续的缩放操作。 
    2 光标和和工具提示 
    和QWidget一样,QGraphicsItem支持图元特定的光标(应用QGraphicsItem::setCursor())和工具提示(QGraphicsItem::setToolTip()).在鼠标进入图元区域时激活相应的光标和工具提示。 
    3 动画 
    QGraphics View支持几种不同级别的动画,可以将动画路径通过QGraphicsItemAnimation和图元关联。这是一使时间线性控制的图元在所有平台上的速度一致。QGraphcisItemAnimation允许创建图元的路径,包括位置,旋转,缩放,扭曲,平移等操作的路径。即在不同的时候进行不同的变换。动画通过常用QTimeLine来控制,也可以用QSlider来控制。也可以创建从QObject和QGraphicsItem继承的图元,此类图元可以设置自己的定时器,通过QObject::timeEvent()来控制动画。 
    4 OpenGL绘制 
    要使用OpenGL绘制,可以调用QGraphicsView::setViewport()来设置QGLWidget作为QGraphicsView的视口,如果需要在OpenGL中打开反锯齿,可以使用QGLFormat::sampleBuffer()来使用OpenGL的采用缓冲区(samplebuffer); 
    5 图元组 
    使用图元组可以将图元组合在一起,对图元组的变换对所有子图元都有效,QGraphpicsItem莪可以处理所有子图元的事件(使用QGraphicsItem::setHandlesChildEvents()),即允许组合图元处理所有子图元的事件。 
    6.8 图形图像的打印 
    Qt提供了夸平台的打印支持,能够使用本地和远程的打印机,Qt的打印系统甚至支持直接生成PostScript可PDF文件,QPrinter类对打印机进行了抽象,他实际上时支持打印的特殊绘图设备(QPainteDevice).QPrinter支持多页和双面打印,使用QPrinter可以和绘制自定义的窗口一样完成打印操作。 
    普通打印过程。 
    QPrinter printer; 
    QPrintDialog *dialog=new QPrintDialog(&printer,this); 
    dialog->setWindowTitle(tr("打印文档")); 
    if(dialog->exec()!=QDialog::Accepted)  return ;  创建了打印设备后及时对打印设备的设置,然后就开始打印  QPainter painter; 
    painter.begin(&printer); 
    for(int page=0;page<numberofPages;++page)  {
      if(page!=lastPage)  printer.newPage(); 
    } 
    painter.end();  paperRect()获取纸张尺寸,pageRect()获取可打印的区域大小 
    void MainWindow::print()  { 
    QPrinter printer; 
    QPrintDialog dialog(&printer,this); 
    if(dialog.exec())  { 
    QPainter painter(&printer); 
    QRect rect=painter.viewport(); 
    QSize size=imageWidget->size(); 
    size.scale(rect.size(),Qt::KeepAspectRatio); 
    painter.setViewport(rect.x(),rect.y(),size.width() ,size.height()); 
    painter.setWindow(imageWidget->rect()); 
    painter.drawPixmap(0,0,QPixmap::grabWidget(imageWi dget,imageWidget->rect())); 
    } 
    } 
    程序将窗口部件上的俄图形用grabWidget()函数抓取到QPixmap对象中,然后直接将QPixmap对象绘制到打印机上。  特殊窗口部件的打印  一些特殊窗口部件的绘制功能是由相应的内容管理类进行管理。如QTextEdit和QGraphicsView显示的内容分别由QTextDocument和QGraphicsScene类管理。对于这些类,他们的打印功能由内容管理类或特定的函数完成。
    这些类如图 
    -------------------------------------------------- 
    QGraphicsView QGraphicsView::render();
     QSvgWidget QSvgRenderer::render(); 
    QTextEdit QTextDocument::print(); 
    QTextLayout QTextLayout::draw(); 
    QTextLine QTextLine::draw() 
    -------------------------------------------------- 
    Graphics View框架通过场景QGraphicsScene::render()函数和视图的QGraphicsView::render()函数结合就可以完成打印工作。这两个函数将场景和视图上的内容全部打印到任意绘图设备。  场景和视图绘制函数的差别就在于一个使用场景坐标,一个使用视图坐标,QGraphicsScene::render()通常用来绘制没有变换的场景,如几何数据,文本文档,QGraphicsView::render()则用来实现屏幕快照,他默认的行为是将视口的数据绘制到指定的绘图所设备。当源区域和目标区域大小不相同时,源区域将会按指定的内容缩放以符合目标区域,缩放比例取决于Qt::AspectRadioMode. 
    void MainWindow::print()  { 
    QPrinter printer; 
    if(QPrintDialog(&printer).exec()==QDialog::Accepte d) 
    { 
    QPainter painter(&printer); 
    painter.setRenderHint(QPainter::Antialiasing); 
    scene->render(&painter); 
    } 
    } 
    用户可以将上面的scene->render(&painter)换为view->render(&painter). 
  • 相关阅读:
    改造vant日期选择
    css3元素垂直居中
    npm综合
    (转)网页加水印方法
    Mac下IDEA自带MAVEN插件的全局环境配置
    隐藏注册控件窗口
    High performance optimization and acceleration for randomWalk, deepwalk, node2vec (Python)
    How to add conda env into jupyter notebook installed by pip
    The Power of WordNet and How to Use It in Python
    背单词app测评,2018年
  • 原文地址:https://www.cnblogs.com/cy568searchx/p/3508505.html
Copyright © 2011-2022 走看看