给QGraphicsView创建刻度轴_第1页
给QGraphicsView创建刻度轴_第2页
给QGraphicsView创建刻度轴_第3页
给QGraphicsView创建刻度轴_第4页
给QGraphicsView创建刻度轴_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、给QGraphicsView创建刻度轴Qt的Scene - Item -View框架功能十分强人,这也是Qt的亮点之一,但由于Qt的设计出发点并不是科 学或石油程序,所以在某些方面提供的功能还不是很全面,比如Scene, Item, View框架并没有提供一套完 整的“刻度”绘制的功能。不过也无可厚非,像MFC, GDK, WxWidget这类GUI库也都不会现成的刻度轴 绘制的内容,当一个库做的越来越优秀时,人们对她的期望和需求变得五花八门由于QGraphicsView中的滚动条和滚动行为都被死死的封装到了 QGraphicsView中,所以试图在ViewPort 或者用QGraphicsI

2、tem来实现刻度轴的作法是十分艰难的,比如使用QGraphicsItem来实现,当一个Scene 和View都固定时,可能我们的"QGraphicsAxisItenT会工作的很好,但当视图变化时,比如滚动,比如重 设SceneRect,比如放缩,比如旋转等等等等。这些行为我们都要考虑,所以难度可想而知。但如果我们了解 J QGraphicsView 是派生于 QAbstractScrollArea 了,并且还知道 QGraphicsArea 有一 个保护成员函数 voidsetViewportMarg;ins ( int left, int top, int right, int b

3、ottom),以及个马甲 voidsetViewportMargins ( const QMargins & margins )的话,事情就变得容易多了。setViewportMargins这个方法就是给QAbstractScrollArea的Viewport留出四边的"空地儿"至于这些 “空地儿”能做什么就根据程序员的爱好了,QT中最典型的使用就是QTableView (就是绘制表格的那个 类),其中的表头就是用这种方法实现的,卞面我就说说这个方法的实现思路,如果您有这个需求并且不 知道怎么实现,劳烦您继续读卞去,如果您在八年前都已经知道此方法了,您也别见笑。首先

4、,实现我们自己的Axis窗II,派生于QWidget,这个类主要注意三个问题,一个是SizeHint方法, 一定要重载,因为我们要在GraphicsView中使用这个方法来决定Margin的人小,第二个注意的问题是刻 度轴中刻度的产生,可以参考Graphics Gem III中一篇叫“Nice label”(记不太清了,好像是这个 名字)的算法。这个算法能帮助我们产生漂亮的刻度值,比如不会出现31415这样的刻度。第三个问题就 是刻度的绘制了,使用PaintEvent函数绘制,这时要注意的就是Offset,因为当用户滚动View时,我们 的刻度也要变化。再一个就是实现我们自己的Graphics

5、View 了,正如之前说的,我们要使用setViewportMargins ()这个方 法,在哪里实现最好呢?在reSizeEventO中实现最好,因为这也正好符合正常逻辑一一当窗II变化时, 重设Margin,并且重设AxisWidget的尺寸,让其铺满Margin区域。另外我们要重载ScrollContentBy(), 目的是设置AxisWidget的Offset。并且滚动四边的刻度窗I I,当然我们可以完全的Update这几个刻度轴, 但还有一个更高效的方法,那就是QWidget的scroll,本人分析过scroll方法的实现,它是用的平台底 层的Bitbit方法(Windows环境),

6、效率可想而知。最后一个要注意的问题就是,当场景人小变化时,要通知刻度轴让其重绘,幸好QGraphicsScene有一个 sceneRectChanged的信号,所以实现这一步也比较简单在AxisWidget中定义一个垂设model的扌巢,并且在Scene实例化后连接这之前的那个信号和这个檢就可以了。根据以上方法实现的带刻度的GraphicsView如卜图:E AxisView上一回一羽【转Qt地图浏览器:使用QGraphicsView2012-02-27 11:31转载H孤舟钓客最终编辑孤舟钓客/* mainwidget.h*孤舟钓客*2011-07-25*/#ifndef MAPWIDGET

7、.H#define MAPWIDGET_Hinclude <QGraphicsView>class QPixmap;class QLabel;class QPointF;class MapWidget: public QGraphicsViewQ_OBJECTpublic:MapWidgetf);void readMapf);QPointF mapToMap(QPointF);public slots:void slotZoom(int);protected:void drawBackground(QPainter painter, const QRectF &rect);

8、 void mouseMoveEvent(QMouseEvent *event);private:QPixmap map;qreal zoom;QLabel *viewCoord;QLabel *sceneCoord;QLabel *mapCoord;double x1, y1;double x2, y2;#endif/MAPWIDGET_H/* mainwidget.cpp*孤舟钓客*2011-07-25*/#include "mapwidgeth11#include <QtGui>#inelude <math.h>MapWidget:MapWidget()

9、readMap(); zoom = 50;int width = map.width(); int height = map.height();QGraphicsScene *scene = new QGraphicsScene(this);scene->setSceneRect(-width/2, -height/2, width, height);setSce ne(sce ne); setCacheMode(CacheBackground);QSlider *slider = new QSlider; slider->setOrientation(Qt:Vertical);

10、slider->setRange(1,100);slider->setTicklnterval(10);slider->setValue(50);connect(slider, SIGNAL(valueChanged(int), this, SLOT(slotZoom(int);QLabel *zoominLabel = new QLabel; zoominLabel->setScaledC on tents(true); zoominLabel-AsetPixmap(QPixmap(”:/images/zoominp ng”);QLabel *zoomoutLabel

11、 = new QLabel; zoomoutLabel->setScaledC on tents(true); zoomoutLabel->setPixmap(QPixmap(":/images/zoomout.pngH);/ create coordiante areaQFrame *coordFrame = new QFrame;QLabel *label1 = new QLabel(tr("GraphicsView viewCoord = new QLabel;QLabel *label2 = new QLabel(tr(HGraphicsScene :H

12、); sceneCoord = new QLabel;QLabel *label3 = new QLabel(tr("mapmapCoord = new QLabel;QGridLayout *grid = new QGridLayout; grid->addWidget(label1, 0, 0);grid->addWidget(viewCoord, 0, 1); grid->addWidget(label2, 1, 0);grid->addWidget(sceneCoord, 1,1); grid->addWidget(label3, 2, 0);g

13、ridaddWidgetfmapCoord, 2, 1); grid->setSizeC on straint(QLayout:SetFixedSize); coordFrame->setLayout(grid);/ zoom layoutQVBoxLayout *zoomLayout = new QVBoxLayout; zoomLayout->addWidget(zoominLabel); zoomLayout->addWidget(slider);zoomLayout->addWidget(zoomoutLabel);/ coordinate area la

14、youtQVBoxLayout *coordLayout = new QVBoxLayout; coordLayout->addWidget(coordFrame); coordLayout->addStretch();QHBoxLayout *layout = new QHBoxLayout; layout->addLayout(zoomLayout); layout->addLayout(coordLayout);layout->addStretch(); layout->setMargin(30);layout->setSpacing(10);

15、setLayout(layout);setWindowTitle("Map Widget"); setMinimumSize(600,400);/ read map informationvoid MapWidget:readMap()QFile mapFile(Hmaps.txtn);QString mapName;int ok = mapFile.open(QIODevice:ReadOnly);if (ok)QTextStream t(&mapFile);if (!t.atEnd()t» mapName;t » x1 » y1 &

16、#187; x2 » y2;mapo ad(mapName);if (map.isNull()printf("map is null"); void MapWidget:slotZoom(int value) qreal s;if (value > zoom)s = pow(1.01, (value-zoom); elses = pow(1/1.01), (zoom-value);scale(s, s);zoom = value;void MapWidget:drawBackground(QPainter *painter, const QRectF &am

17、p;)painter->drawPixmap(int(sceneRect()Jeft(), int(sceneRect().top(), map);void MapWidget:mouseMoveEvent(QMouseEvent *event)/ view coordinateQPoint viewpoint = event->pos();viewCoord->setText(QString:number(viewPoint.x() + ",H + QString:number(viewPoint.y();/ seene coordinateQPointF sce

18、nePoint = mapToScene(viewPoint);sceneCoord->setText(QString:number(scenePoint.x() + M," + QString:number(scenePoint.y();II map coordinateQPointF latLon = mapToMap(scenePoint);mapCoord->setText(QString:number(latLon.x() + ",H + QString:number(latLon.y();/ map seene coordinate to mapQP

19、ointF MapWidget:mapToM即(QPointF p)QPointF latLon;qreal w = sceneRect().width();qreal h = seeneRect()height();qreal Ion = y1 - (h/2 + p.y()*abs(y1-y2)/h);qreal lat = x1 + (w/2 + p.x()*abs(x1-x2)/w);latLon.setX(lat);latLon.setY(lon);return latLon;/* main.cpp*孤舟钓客*2011-07-25*/ #inelude <QApplication

20、>include “mapwidget.h” int main(int argc, char * argv)QApplication app(argc, argv);MapWidget map;map.show();return app.exec();类別:默认分类II添加到搜藏I分亨到i贴吧浏览(15)评论(0)上一篇:Qt串口通信专题教程QT 的 Graphics View 柜架(3/3)Posted on 2011-05-14 14:55 Jianqwzh 阅读(298)评论(0)编辑 收藏.关键特性缩放与旋转 QGraphicsView通过QGraphicsView:setMat

21、rix()支持同QPainter 样的仿射变换,通过对一个视图应用变换,你可 以很容易地支持普通的导航特性如缩放与旋转。下面是一个例子:class View:;public QGraphicsViewQ_OBJECT/public slots:void zoomln() scale(l.2,1-2);void zoomOut() scale(l/1.2,l/1.2);void rotateLeft() (rotate(-lO);void rotateRight() rotate(lO);这些槽应与QToolButtons联接,并使autoRepeat有效。当对视图变换时,QGraphicsVi

22、ew会对视图中心进行校正。拖拽因为QGraphicsView继承自QWidget,它也提供了像QWidget那样的拖拽功能,另处,为了方便,Graphics View柜 架也为场衆,每个item提供拖拽支持。当视图接收到拖拽事件,它可翻译为QGraphicsSceneDragDropEvent,再发送 到场景。场景接管这个事件,把它发送到光标下接受拖拽的第一个item.从一个item开始拖拽时,创建一个QDrag对象,传递开始拖拽的那个widget的指针。Items可以同时被多个视图观察, 但只有一个视图可以开始拖拽。拖拽在多数情况下是从按下鼠标或是移动鼠标开始的,因此,在mousePress

23、Event()或 mouseMoveEvent()中,你可以从事件中得到那个原始的widget指针,例如:void Customitem :mousePressEvent(QGraphicsSceneMouseEve nt * eve nt)QMimeData *data=new QMimeData;data->setColor(Qt:green);QDrag *drag=new QDrag(event?>widget();drag->setMimeData(data);drag->start();为了在场景中载収拖拽事件,你应重新实现QGraphicsScene:dr

24、agEnterEvent()和在QGraphicsItem的子类里任何与 你特定场衆需要的事件处理器。items也可以通过调用QGraphicsItem:setAcceptDrops()获得拖拽支持,为了处理将 要 进 行 的 拖 拽,你 需 要 重 新 实 现QGraphicsItem: :dragE nterEve nt()QGraphicsItem :dragMoveEvent(),QGraphicsItem: :dragLeaveEve nt() 和 QGraphicsItem: :dropEvent()<>光标与工具提示像 QWidget 一 样,QGraphicsItem 也支持光标(Qgraphicsltem:setCursor)与工具提示 (QGraphicsItem:setToolTip()o当光标进入到item的区域,光标与工具提示被QGraphicsView激活(通过调用 QGraphicsItem:contains()检测)。你也可以直接在视图上设呂一个缺省光标(QGraphicsView:setCursor)3动画Graphics View支持几种级别的动画。你可以很容易地通过把QGraphicsItemAnimatoin与你的item联结来装配出动画路径

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论