qt下绘图

绘图

Qt的二维绘图基本功能是使用QPainter在绘图设备上绘图
绘图设备包括QWidget, QPixmap

Qt还提供了Graphics View架构
使用QGraphicsView,QGraphicsScene,和各种QGraphicsItem类绘图
且每个图件是可选择,可交互的
Graphics View架构为绘制复杂组件化图形提供了便利

QPainter基本绘图

QPainter绘图系统

- QPainterQPaintDevice
Qt的绘图系统使用户可在屏幕或打印设备上用相同的Api绘图,
绘图系统基于QPainter, QPaintDeviceQPaintEngine
QPaintDevice是一个可使用QPaint进行绘图的抽象的二维界面
QPaintEngineQPainter提供在不同设备上绘图的接口
QPaintEngine类由QPainterQPaintDevice内部使用
一般的绘图设备包括QWidget, QPixmap, QImage
这些绘图设备为QPainter提供一个画布
- paintEvent事件和绘图区
QWidget类及其子类是最常用的绘图设备
QWidget类继承的类都有paintEvent()事件,要在设备上绘图,只需重定义此事件并编写响应代码
创建一个QPainter对象获取绘图设备接口,就可在绘图设备的画布上绘图了

void x::paintEvent(QPaintEvent* event)
{
	QPainter painter(this);
	...
}

绘图区的宽度由QWidget::width()获取
高度由QWidget::height()获取
视口坐标[viewport
逻辑坐标窗口坐标

QPainter绘图的主要属性

绘制基本图形元素:点,直线,圆形, 矩形,曲线,文字等
控制这些绘图元素特性的主要是QPainter个属性,分别是:
- pen属性,
是一个QPen对象,用于控制线条的颜色,宽度,线型等
- brush属性
是一个QBrush对象,用于设置一个区域的填充特性,可设置填充颜色,填充方式,渐变特性等
还可采用图片作材质填充
- font属性
是一个QFont对象,用于绘制文字时,设置文字的字体样式,大小等属性

创建实例

Q_DECL_OVERRIDE宏,表示函数是对父类虚函数的重载
QWidget支持void x::paintEvent(QPaintEvent*),int width(),int height()
QRect,QPen支持void setWidth(...),void setColor(...),void setStyle(...),void setCapStyle(...),void setJoinStyle(..)

QPainter支持void setRenderHint(...),void setPen(...),void setBrush(...),void drawRect(...)
QBrush支持void setColor(...),void setStyle(...)

QPen的主要功能

QPen的主要函数.void setColor(...),void setWidth(...),void setStyle(...),void setCapStyle(...),void setJoinStyle(...)

线条样式

Qt::SolidLine,Qt::DashLine,Qt::DotLine,Qt::DashDotLine,Qt::DashDotDotLine,Qt::CustomDashLine

线条端点样式

Qt::SquareCap,Qt::FlatCap,Qt::RoundCap

线条连接样式

Qt::BeveJoin,Qt::MiterJoin,Qt::RoundJoin

QBrush的主要功能

QBrush的主要函数.void setColor(...),void setStyle(...),void setTexture(...),void setTextureImage(...)

枚举类型Qt::BrushStyle
Qt::NoBrush,Qt::SolidPattern,Qt::HorPattern,Qt::VerPattern,Qt::LinearGradientPattern,Qt::RadialGradientPattern,Qt::ConicalGradientPattern,Qt::TexturePattern

渐变填充

使用渐变填充需要用渐变类的对象作为Painterbrush
个实现渐变填充的类
-对QLinearGradient
线性渐变
-对QRadialGradient
简单辐射渐变,扩展辐射渐变
-对QConicalGradient
圆锥形渐变
三个类均继承自QGradient
QGradient支持void setSpread(...)
-对PadSpread
-对RepeatSpread
-对ReflectSpread

QPainter绘制基本图形元件

基本图形元件

QPainter绘制基本图形元件的函数
如,drawArc,drawChord,drawConvexPolygon,drawEllipse,drawImage,drawLine,drawLines,drawPath,drawPie,drawPixmap,drawPoint,drawPoints,drawPolygon,drawPolyline,drawRect,drawRoundedRect,drawText,,eraseRect,fillPath,fillRect

QPainterPath的使用

QPainterPath是一系列绘图操作的顺序集合,便于重复使用
一个PainterPath由许多基本的绘图操作组成,
一个闭合的PainterPath是终点和起点连接起来的绘图路径

坐标系统和坐标变换

坐标变换函数

QPainter在窗口上绘图的默认坐标系统,称为绘图设备的物理坐标
通过变换,基于物理坐标得到逻辑坐标或相反
QPainter有关坐标变换操作的函数
对坐标变换,支持void translate(...),void rotate(...),void scale(...),void shear(...)
对状态保存与恢复,支持void save(),void restore(),void resetTransform()

QTransform直接应用变换矩阵,更灵活

坐标平移

支持void translate(qreal x, qreal y)实现像素移动

坐标旋转

支持void rotate(qreal)

缩放

void scale(qreal, qreal)// 横向,纵向缩放比例

状态保存与恢复

坐标变换绘图实例

绘制3个五角星的程序

QPainterPath支持void moveTo(...),void lineTo(...),void closeSubpath(),void addText(...)

绘制五角星的PainterPath的定义

视口和窗口

视图和窗口的定义与原理

绘图设备的物理坐标是基本的坐标系
通过QPainter的平移,旋转等变换可得到更多更易操作的逻辑坐标
为实现更方便的坐标,QPainter还提供了视口,窗口坐标系

// 指定视口原点设备坐标下的位置
// 指定视口宽度,高度
void QPainter::setViewport(int x, int y, int width, int height)
// 窗口左上角逻辑坐标,串口宽度,高度	
void QPainter::setWindow(int x, int y, int width, int height) 	
视口和窗口的使用实例

使用窗口坐标的优点是,只需按窗口坐标定义来绘图,不管实际物理坐标范围大小
QPainter支持void drawRect(...),void setViewport(...),void setWindow(...),void setRenderHint(...),void setPen(...),void drawEllipse(...),void rotate(...)

QPoint,QPen支持void setWidth(...),void setColor(...),void setStyle(...)
QRect,QWidget支持int width(),int height()

绘图叠加的效果

QPainter支持void setBrush(...),void setCompositionMode(...)
QLinearGradient ,支持void setColorAt(...),void setColorAt(...),void setSpread(...)

Graphics View

场景,视图,图形项

paintEvent()里的绘图程序,不能实现图元的选择,编辑,拖放,修改等
Qt为绘制复杂的可交互图形提供了Graphics View绘图架构,是一种基于图形项的模型/视图模式
使用Graphics View架构可绘制复杂的有几万个基本图形元件的图形,且每个图形元件是可选择,可拖放,修改的.
Graphics View架构主要由个部分组成:
场景,视图,图形项

场景

QGraphicsScene类提供绘图场景
场景不可见,是一个抽象的管理图形项的容器
可向场景添加图形项,获取某个图形项等
- 提供管理大量图形项的快速接口
- 将事件传播给每个图形项
- 管理每个图形项的状态,如选择状态,焦点等
- 管理未经变换的渲染功能,主要用于打印
除了图形项
场景还有背景层和前景层,通常由QBrush指定,
也可通过重新实现drawBackground()和drawForeground()函数来实现自定义的背景和前景,实现一些特殊效果

视图

QGraphicsView提供绘图的视图组件,用于显示场景中的内容
可为一个场景设置几个视图,用于对同一个数据集提供不同的视口

缺省下,当视图大于场景时,
场景在视图的中间部分显示,也可设置视图的Alignment属性控制场景在视图中的显示位置
当视图小于场景时,视图显示场景一部分内容,可提供滚动显示
视图接收键盘和鼠标输入并转换为场景事件,进行坐标转换后,传送给可视场景.

图形项

图形项是一些基本的图元元件
图形项的基类是QGraphicsItem
Qt提供了一些基本的图形项,
如绘制椭圆的QGraphicsEllipseItem
绘制矩形的QGraphicsRectItem
绘制文字的QGraphicsTextItem

QGraphicsItem支持如下的一些操作:
- 支持鼠标事件响应
包括鼠标按下,移动,释放,双击,还包括鼠标停留,滚轮,快捷菜单等事件
- 支持键盘输入,按键事件
- 支持拖放操作
- 支持组合,可以是父子项关系组合,也可是通过QGraphicsItemGroup类进行组合
故,图形项可被选择,拖放,组合,
若编写信号槽函数代码,还可实现各种编辑功能
一个图形项还可包含子图形项,图形项还支持碰撞检测

Graphics View的坐标系统

Graphics View有三个有效的坐标系,
图形项坐标,场景坐标,视图坐标
场景的坐标等价于QPainter的逻辑坐标
一般以场景的中心为原点
视图坐标与设备坐标相同,是物理坐标,缺省以左上角为原点
图形项坐标是局部逻辑坐标,一般以图件的中心为原点

图形项坐标

图形项使用自己的局部坐标,
通常以其中心为(0, 0)
也是各种坐标交换的中心

图形项的鼠标事件的坐标是用局部坐标表示的
创建自定义图形项
绘制图形项时只需考虑其局部坐标
QGraphicsSceneQGraphicsView会自动进行坐标转换

一个图形项的位置是其中心点在父坐标系统中的坐标
对没有父图形项的图形项,其父对象就是场景,图形项的位置就算在场景中的坐标
如一个图形项还是其他图形项的父项,父项进行坐标变换时,子项也做同样的坐标变换
QGraphicsItem::boundingRect()是用局部坐标给出的,
QGraphicsItem::pos()是仅有的几个例外
它返回的是图形项在父项坐标系中的坐标,如是顶层图形项,就是在场景中的坐标

视图坐标

视图坐标所窗口界面的物理坐标
单位是像素
视图坐标只与widget或视口有关,
与观察的场景无关

QGraphicsView视口的左上角坐标总是(0,0)
所有的鼠标事件,拖放事件的坐标先是由视图坐标定义的,用户需要将这些坐标映射为场景坐标

场景坐标

场景是所有图形项的基础坐标
场景坐标描述了每个顶层图形项的位置
创建场景时可定义场景矩形区的坐标范围
QGraphicsScene,每个图形项在场景里都有一个位置坐标
由函数QGraphicsItem::scenePos()给出,还有一个图形项边界矩形,由QGraphicsItem::sceneBoundingRect()函数给出
边界矩形可使QGraphicsScene知道场景的那个区域发生了变换
场景发生变化时,会发射QGraphicsScene::changed()信号
参数是一个场景的矩形列表

坐标映射

在场景中操作图形项时,进行场景到图形项,图形项到图形项或视图到场景之间的坐标变换比较有用
QGraphicsView的视口上单击鼠标时,通过函数QGraphicsView::mapToScene()可将视图坐标映射为场景坐标
然后用QGraphicsScene::itemAt()可获取场景中鼠标光标处的图形项

Graphics View相关的类

Graphics View结构的主要类包括
视图类QGraphicsView
场景类QGraphicsScene
各种图形项类,图形项类的基类都算QGraphicsItem
- QGraphicsView类的主要接口函数
QGraphicsView是用于观察一个场景的物理窗口
场景小于视图时,整个场景视图内可见
场景大于视图时,视图自动提供滚卷条
QGraphicsView的视口坐标等于显示设备的物理坐标
也可对QGraphicsView的坐标进行平移,旋转,缩放等变换
QGraphicsView的主要接口函数
一般的设置函数还有一个对应的读取函数
setScene()对应scene()
这里只列设置函数
QGraphicsView主要函数功能说明

void setScene(...)
void setSceneRect(...)
	
void setAlignment(...)
void setBackgroundBrush(...)
void setForegroundBrush(...)
void setRenderHints(...)

void setInteractive(...)
QRect rubberBandRect(...)
void setRubberBandSelectionMode(...)
QGraphicsItem* itemAt(...)
QList<QGraphicsItem*> items(...)

QPoint mapFromScene(...)
QPointF mapToScene(...)
QGraphicsScene类的主要接口函数

QGraphicsScene用于管理图形项的场景,是图形项的容器
有添加,删除图形项的函数
管理图形项的各种函数
QGraphicsScene主要函数功能说明

void setSceneRect(...)
QGraphicsItemGroup* createItemGroup(...)
void destroyItemGroup(...)
QGraphicsItem* focusItem(...)
void clearFocus(...)
bool hasFocus(...)	
void addItem(...)
void removeItem(...)
void clear(...)
QGraphicsItem* mouseGrabberItem(...)
QList<QGraphicsItem*> selectedItems(...)
void clearSelection(...)
QGraphicsItem* itemAt(...)
QList<QGraphicsItem*> items(...)
QGraphicsEllipseItem* addEllipse(...)
QGraphicsLineItem* addLine(...)
QGraphicsPathItem* addPath(...)
QGraphicsPixmapItem* addPixmap(...)
QGraphicsPolygonItem* addPolygon(...)
QGraphicsRectItem* addRect(...)
QGraphicsSimpleTextItem* addSimpleText(...)
QGraphicsTextItem* addText(...)
QGraphicsProxyWidget* addWidget(...)
图形项

QGraphicsItem是所有图形项的基类
用于可从QGraphicsItem继承定义自己的图形项
Qt定义了一些常见的图形项,这些常见的图形项的类的继承关系如图
QGraphicsItem直接派生了QAbstractGraphicsShapeItem,QGraphicsLineItem,QGraphicsPixmapItem,QGraphicsObject,QGraphicsItemsGroup

QAbstractGraphicsShapeItem直接派生了QGraphicsEllipseItem,QGraphicsPathItem,QGraphicsPolygonItem,QGraphicsRectItem,QGraphicsSimpleTextItem

QGraphicsObject直接派生了QGraphicsTextItem
QGraphicsItem类提供了图形项操作的函数,常见的函数如下
QGraphicsItem主要函数

void setFlags(...)
void setOpacity(...)
void setGraphicsEffect(...)
void setSelected(...)
void setData(...)

void setX(...)
void setY(...)
void setZValue(...)
void setPos(...)
QPointF scenePos(...)

void resetTransform(...)
void setRotation(...) // 正数表示顺时针旋转
void setScale(...)

QPointF mapFromItem(...)
QPointF mapFromParent(...)
QPointF mapFromScene(...)
QPointF mapToItem(...)
QPointF mapToParent(...)
QPointF mapToScene(...)

常见标志:

QGraphicsItem::ItemIsMovable
QGraphicsItem::ItemIsSelectable
QGraphicsItem::ItemIsFocusable

Graphics View程序基本结构和功能实现

实例程序功能

- 工作区是一个从QGraphicsView继承得到自定义类QWGraphicsView
作为绘图的视图组件
- 创建一个QGraphicsScene场景
- 改变窗口大小
视图大于场景时,显示在视图中央
视图小于场景时,视图窗口可滚动显示
- 蓝色椭圆处于场景中间
红色圆形位于场景右下角
- 鼠标在窗口上移动时,
状态栏显示光标的视图坐标,场景坐标
在某个图形项上单击鼠标时,还显示图形项中的局部坐标

自定义图形视图组件

QGraphicsViewQGraphicsView继承定义一个类QWGraphicsView,实现mouseMoveEvent()事件和mousePressEvent()事件,把鼠标事件转换为信号

自定义信号
类定义中,进行信号函数声明
触发信号处,采用emit 信号函数(实参列表); 来触发信号

QMouseEvent支持QPoint pos(),? button()

主窗口类定义与QGraphicsView组件升级

QMainWindow类继承的类
resizeEvent()事件

QMainWindow支持void resizeEvent(QResizeEvent*)

窗口初始化

QGraphicsView

void setCursor(...)
void setMouseTracking(...)
void setDragMode(...)
// 依据视图坐标得到场景坐标
QPointF mapToScene(...)
int width()
int height()
QRectF sceneRect()

对QRectF支持:

int top()
int left()
int width()
int height()

QString支持QString asprintf(...)
QGraphicsScene支持QGraphicsItem* itemAt(QPointF, QTransform)
QGraphicsItem支持QPointF mapFromScene(...)

Graphics View系统初始化

QRectF,QGraphicsScene支持QGraphicsScene(QRectF),void addItem(...),void clearSelection()
QGraphicsView支持void setScene(QGraphicsScene*)
QGraphicsRectItem/QGraphicsEllipseItem/QGraphicsEllipseItem支持QGraphicsItem(QRectF),void setPos(...),void setFlags(...)

可视化设计窗体时,将QWGraphicsView类对象名称命名为View,且自动填充主窗口工作区

Graphics View绘图程序实例

实例功能

- 可创建矩形,椭圆,圆形,三角形,梯形,直线,文字等基本图形项
- 每个图形项都可被选择和拖动
- 图形项或整个视图可缩放和旋转
- 图形项重叠时,可调整前置或后置
- 多个图形项可组合,可解除组合
- 可删除选择的图形项
- 鼠标在视图上移动时,
会在状态栏显示视图坐标和场景坐标
- 鼠标单击某个图形项时,会显示图形项的局部坐标,会显示图形项的文字描述和编号
- 双击某个图形项时,会根据图形项的类型调用颜色对话框或字体对话框,
设置图形项的填充颜色,线条颜色,或文字的字体
- 选中某个图形项时,可进行按键操作,
Delete键删除图形项,
PgUp放大,
PgDn缩小
空格键旋转90
上下左右光标键移动图形项

自定义图形视图类QWGraphicsView

事件处理--发自定义信号---设计槽函数处理
QMouseEvent支持QPoint pos(),? button()

主窗口设计

主窗口是一个从QMainWindow继承的窗口类MainWindow
采用可视化设计
利用Action创建两个工具栏
一个用于图形项的创建
一个用于图形项的各种操作

ItemIdItemDesciption用于定义图形项的自定义数据的键
seqNum用于给每个图形项编号,
frontZ用于设置图形项的叠放顺序,数值越大,越在前面显示
backZ用于设置图形项的叠放顺序,数值越小,越在后面显示

QGraphicsScene支持new QGraphicsScene(...)// 场景坐标系
QGraphicsView

void setScene(...)// 视图与场景关联
void setCursor(...)//
void setMouseTracking(...)
void setDragMode(...)

QWidget支持void setCentralWidget(...),qsrand(...)// 随机数初始化

图形项的创建

主窗口左侧工具栏上的按钮用于创建各种标准的图形项
创建矩形使用QGraphicsRectItem
创建椭圆和圆使用QGraphicsEllipseItem
创建三角形和梯形使用QGraphicsPolygonItem
创建直线使用QGraphicsLineItem
创建文字使用QGraphicsTextItem
还有一些其他的标准图形项类

QGraphicsEllipseItem支持:

new QGraphicsEllipseItem(...)// 建立图形项坐标系
void setFlags(...)
void setBrush(...)
void setZValue(...)
void setPos(...)// 图形项中心在场景坐标系的位置
void setData(...)// 键值对
void setSelected(...)

QGraphicsScene

void addItem(...) // 将QGraphicsItem与QGraphicsScene绑定
void clearSelection()

多个图形项叠加在一起时,ZValue最大的显示在最前面

图形项操作

主窗口的另一个工具栏上的按钮实现图形项的缩放,旋转,组合等
- 缩放
QGraphicsScene支持? selectedItems()
QGraphicsItem支持void setScale(...)
QGraphicsView支持void scale(...)
- 旋转
QGraphicsItem支持void setRotation(...),int rotation()
QGraphicsView支持void rotate(...) // 正值表示顺时针旋转
- 恢复坐标变换
QGraphicsItem支持void resetTransform()
QGraphicsView支持void resetTransform()
- 叠放顺序
QGraphicsItemzValue()表示图形项在Z轴的值
若有多个图形项叠加在一起
zValue()值最大的显示在最前面
zValue()值最小的显示在最后面
setZValue()可设置这个属性值
QGraphicsItem支持int zValue(),void setZValue(...)
- 图形项的组合
可将多个图形项组合为一个图形项
当做一个整体进行操作
使用QGraphicsItemGroup类实现多个图形项的组合
QGraphicsItemGroupQGraphicsItem的子类

QGraphicsScene支持void addItem(...),void clearSelection()
QGraphicsItem支持void setSelected(...),void clearFocus()
QGraphicsItemGroup支持void addToGroup(...),void setFlags(...),void setZValue(...),void setSelected(...)

一个组合对象也可被打散
使用QGraphicsScenedestroyItemGroup()可打散一个组合对象
这个函数打散组合,删除组合对象
但不删除原来组合里的图形项

QGraphicsScene支持void destroyItemGroup(...)

- 图形项的删除
使用QGraphicsSceneremoveItem()函数删除某个图形项
QGraphicsScene支持void removeItem(....),? selectedItems()

鼠标与键盘操作

- 鼠标移动
鼠标在绘图视图上移动时,在状态栏显示光标处的视图坐标和场景坐标
时间参数为视图坐标
QGraphicsView支持QPointF mapToScene(...)// 视图坐标映射到场景坐标
- 鼠标单击
显示图形项局部坐标
提取其自定义信息进行显示
QGraphicsScene支持QGraphicsItem* itemAt(...)// 依据场景坐标在场景中进行命中测试

QGraphicsItem

QPointF mapFromScene(...)// 由场景坐标得到图形项局部坐标
QVariant data(...)// 依据键,获取对应的值

- 鼠标双击
QGraphicsView支持QPointF mapToScene(...) // 将视图坐标映射到场景坐标
QGraphicsScene支持QGraphicsItem* itemAt(...)// 依据场景坐标,视图变换进行命中测试
QGraphicsItem支持int type(),qgraphicsitem_cast<X*>(xx)// QGraphicsItem基类到派生类的显示指针类型转换

QGraphicsLineItem支持QPen pen(),void setPen(...)
QPen支持QColor color(),void setColor(...)
QColorDialog支持QColor getColor(...)
QGraphicsTextItem支持QFont font(),void setFont(...)
QFontDialog支持QFont getFont(...)

自定义一个图形项时,需定义枚举常量Type和函数type
枚举常量Type的值必须大于UserType

模板函数

template<class T>
void setBrushColor(T* item)
{
	QColor color = item->brush().color();
	color = QColorDialog::getColor(color, NULL, "选择填充颜色");
	if(color.isValid())
		item->setBrush(QBrush(color));
}

- 按键操作
QGraphicsScene支持void removeItem(...)
QGraphicsItem

void setRotation(...)
int rotation()
void setScale(...)
int scale()
void setX(...)
int x()
void setY(...)
int y()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值