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).