何时使用Qt图形浮点类?
Qt有一组图形类,有两种变体:整数精度和浮点精度何时使用Qt图形浮点类?,qt,Qt,Qt有一组图形类,有两种变体:整数精度和浮点精度 这些是我能记得的 | QLine | QLineF | | QMargins | QMarginsF | | QPoint | QPointF | | QRect | QRectF | | QSize | QSizeF | 除了明显的区别,一个使用整数,另一个使用浮点数,正如他们的名字和官方文件中所说的那样,我有相当多的疑问 一个类家族和另一个类家族的用例是什么 位置和大小是否大于其整数对应项 分数
这些是我能记得的
| QLine | QLineF |
| QMargins | QMarginsF |
| QPoint | QPointF |
| QRect | QRectF |
| QSize | QSizeF |
除了明显的区别,一个使用整数,另一个使用浮点数,正如他们的名字和官方文件中所说的那样,我有相当多的疑问
- 一个类家族和另一个类家族的用例是什么
- 位置和大小是否大于其整数对应项
- 分数值
- 画画的时候有什么不同吗
- 如果使用QLineF而不是QLine,绘图是否更平滑
>>> p = QtCore.QPoint(1, 1)
>>> r = QtCore.QRect(0, 0, 1, 1)
>>> print(r.contains(p))
False
>>> r = QtCore.QRectF(0, 0, 1, 1)
>>> print(r.contains(p))
True
这是因为QRect只考虑整数(“像素”)大小,显然(1,1)
位于“另一个像素”上
QRect对于和函数也是特殊的,因为(如文档中所述)由于历史原因,它们总是返回left+width-1
和top+height-1
:
>>> r = QtCore.QRect(0, 0, 1, 1)
>>> print(r.right())
0
有鉴于此,请始终记住,这些坐标的设置器(包括set*
和move*
)也同样适用:
浮点类还具有基于整数的类所不具备的功能(主要是因为实现它们是不可能的/有用的/合理的)。例如,QLineF类:
- 可以返回与另一个QLineF(或其扩展的交点)的交点李>
- 具有获取和设置直线自身角度(从其
起点)或与另一条直线创建的角度(或者,更好的是,如果它们不相交,则其延伸)的函数[1]李>p1
- 可以从极轴创建,给定长度和角度李>
例如,以下内容将给出非常不同的结果:
painter.setRenderHints(painter.Antialiasing)
painter.drawRect(QtCore.QRect(1, 1, 2, 2))
painter.drawRect(QtCore.QRectF(1, 1, 2.5, 2.5))
<> P> >重要的是记住,所有接受数值作为主要参数的Q画师的简单绘图函数总是使用整数值(我相信这是由于Python的动态类型,因为C++函数只接受有符号整数):
最后,虽然Qt(和Python)有时允许两种类型的透明使用,但通常严格要求使用其中一种:
- 所有与几何图形相关的小部件函数只接受整数类(
,setGeometry(QRect)
,等等)李>resize(QSize)
- 对于必须返回几何值的函数重写也是如此,例如
、项模型的sizeHint()
、由QStyle子类返回的矩形或为QStyleOption设置的矩形李>SizeHintRole
- QRegion只能接受QPolygon和QRect,因为它是一个像素映射对象李>
- QGraphicsRecItem、QGraphicsSellipseItem和QGraphicsPolygonItem仅允许其构造函数或setter中的浮点类李>
- 复杂构造函数使用其精度类型的类(QRect不接受QPointF或QSizeF等)李>
- 所有映射QGraphicsCENE坐标的函数在映射到场景时必须使用整数类,从场景映射时必须使用浮点类李>
to[*]
函数即可:
intRect = QtCore.QRect(0, 0, 10, 10)
floatRect = QtCore.QRectF(intRect)
newIntRect = floatRect.toRect()
intTopLeft = floatRect.topLeft().toPoint()
intSize = floatRect.size().toSize()
midRadiusLine = QtCore.QLineF.fromPolar(
intRect.width() * .5, 45).translated(floatRect.center())
intMidRadiusLine = midRadius.toLine()
[1] 请注意,设置0-360范围之外的角度可能会产生意外结果:
line.setAngle(361)
将导致line.angle()
等于0.999999999748,这是由于浮点“[im]精度”和Pi的性质。是的,可以使用fp值在亚像素边界上定位对象。确定,这有点道理,但Qt文档在这方面有点欠缺。
painter.drawRect(0.5, 0.5, 5.5, 5.5)
# same as:
painter.drawRect(0, 0, 5, 5)
# so you should use:
painter.drawRect(QtCore.QRectF(0.5, 0.5, 5.5, 5.5))
intRect = QtCore.QRect(0, 0, 10, 10)
floatRect = QtCore.QRectF(intRect)
newIntRect = floatRect.toRect()
intTopLeft = floatRect.topLeft().toPoint()
intSize = floatRect.size().toSize()
midRadiusLine = QtCore.QLineF.fromPolar(
intRect.width() * .5, 45).translated(floatRect.center())
intMidRadiusLine = midRadius.toLine()