QRectF类详细介绍

**QRectF 类详解及常用方法**

QRectF 是 PyQt5 中用于表示 ​浮点精度矩形区域 的类,继承自 QtCore 模块。它常用于图形绘制、布局计算、碰撞检测等场景,支持高精度的坐标计算。以下是其核心功能、常用方法及示例:

一、核心功能

  • 坐标表示:用浮点数定义矩形的左上角坐标(x, y)、宽度(width)和高度(height)。
  • 几何运算:计算交集、并集、移动位置、调整大小。
  • 边界检测:判断点或矩形是否在区域内。
  • 单位转换:与整数矩形 QRect 互相转换(注意精度丢失)。

 

二、构造函数

构造函数说明示例
QRectF()创建空矩形((0,0,0,0)rect = QRectF()
QRectF(x: float, y: float, width: float, height: float)通过坐标和尺寸创建rect = QRectF(10.5, 20.3, 100.2, 50.7)
QRectF(QPointF, QSizeF)通过左上角点 + 尺寸创建rect = QRectF(QPointF(10, 20), QSizeF(100, 50))
QRectF(QPointF_topLeft, QPointF_bottomRight)通过左上角和右下角点创建rect = QRectF(QPointF(10, 20), QPointF(110, 70))

三、常用方法

1. 属性获取
方法说明示例
x() -> float左上角 X 坐标x = rect.x()
y() -> float左上角 Y 坐标y = rect.y()
width() -> float矩形宽度w = rect.width()
height() -> float矩形高度h = rect.height()
top() -> float上边界 Y 坐标(等价于 y()top = rect.top()
left() -> float左边界 X 坐标(等价于 x()left = rect.left()
bottom() -> float下边界 Y 坐标( + height()bottom = rect.bottom()
right() -> float右边界 X 坐标(x() + width()right = rect.right()
center() -> QPointF中心点坐标center = rect.center()
2. 几何运算
方法说明示例
contains(QPointF) -> bool判断点是否在矩形内rect.contains(QPointF(50, 50))
intersects(QRectF) -> bool判断两矩形是否相交rect1.intersects(rect2)
intersected(QRectF) -> QRectF返回两矩形的交集overlap = rect1.intersected(rect2)
united(QRectF) -> QRectF返回两矩形的并集merged = rect1.united(rect2)
adjusted(dx1: float, dy1: float, dx2: float, dy2: float) -> QRectF调整矩形大小(左/上边移动 dx1, dy1,右/下边移动 dx2, dy2new_rect = rect.adjusted(5, 5, -5, -5)
3. 修改属性
方法说明示例
setX(x: float)设置左上角 X 坐标rect.setX(15.5)
setY(y: float)设置左上角 Y 坐标rect.setY(25.5)
setWidth(w: float)设置宽度rect.setWidth(200)
setHeight(h: float)设置高度rect.setHeight(100)
moveTo(x: float, y: float)移动矩形到新位置(保持尺寸)rect.moveTo(30, 40)
translate(dx: float, dy: float)平移矩形(相对当前位置)rect.translate(10, -5)
4. 类型转换
方法说明示例
toRect() -> QRect转换为整数矩形 QRect(截断小数)int_rect = rect.toRect()
toAlignedRect() -> QRect转换为整数矩形(四舍五入)int_rect = rect.toAlignedRect()

四、代码示例

1. 基本操作

python

from PyQt5.QtCore import QRectF, QPointF

# 创建矩形
rect = QRectF(10.5, 20.5, 100.0, 50.0)
print(f"坐标: ({rect.x()}, {rect.y()}), 尺寸: {rect.width()}x{rect.height()}")  # 输出: (10.5, 20.5), 100.0x50.0

# 判断点是否在矩形内
point =F(60.0, 45.0)
print(f"点是否在矩形内: {rect.contains(point)}")  # 输出: True

# 计算交集
rect2 = QRectF(50.0, 30.0, 80.0, 60.0)
overlap = rect.intersected(rect2)
print(f"交集矩形: ({overlap.x()}, {overlap.y()}, {overlap.width()}, {overlap.height()})")
2. 图形绘制

python

from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter

class Canvas(QWidget):
    def paintEvent(self, event):
        painter = QPainter(self)
        rect = QRectF(50.5, 50.5, 200.2, 150.7)
        painter.drawRect(rect)  # 绘制矩形(自动转换为整数坐标)

app = QApplication([])
window = Canvas()
window.show()
app.exec_()

五、与 QRect 的区别

QRectFQRect
使用 float 存储坐标和尺寸使用 int 存储坐标和尺寸
适用于高精度计算(如图形变换)适用于像素级操作(如控件布局)

六、注意事项

  • 浮点精度问题:避免直接比较浮点数的相等性(如 rect.x() == 10.5),应使用容差判断。
  • 性能优化:频繁的矩形运算可能影响性能,建议在必要时缓存计算结果。
  • 坐标系统:PyQt5 的默认坐标系以左上角为原点 (0,0),向右为 X 轴正方向,向下为 Y 轴正方向。

通过 QRectF,可以轻松处理复杂的几何计算,适用于需要高精度的图形绘制和动态布局场景!

好的,下面我来详细介绍一下用Qt制作函数图像绘制器的步骤。 1. 创建一个Qt窗口应用程序 首先,在Qt Creator中创建一个新的Qt窗口应用程序,命名为FunctionPlotter。 2. 创建UI界面 在Qt Designer中创建UI界面,包含以下控件: - 一个QLabel用于显示函数输入框的提示信息 - 一个QLineEdit用于输入函数 - 一个QPushButton用于设置函数并绘制图像 - 一个QPushButton用于清除图像 - 一个QPushButton用于保存图像 - 一个QGraphicsView用于显示绘制的图像 在UI界面中,使用布局管理器将控件布局好。 3. 编写绘制函数的代码 在FunctionPlotter中,声明一个私有成员变量QGraphicsScene *_scene,并在构造函数中初始化: ``` FunctionPlotter::FunctionPlotter(QWidget *parent) : QMainWindow(parent) , ui(new Ui::FunctionPlotter) { ui->setupUi(this); _scene = new QGraphicsScene(this); ui->graphicsView->setScene(_scene); } ``` 接着,编写绘制函数的代码。这里我们使用QPainter绘制函数图像,将绘制的图像添加到QGraphicsScene中,并更新QGraphicsView显示出来。 ``` void FunctionPlotter::drawFunction(const QString &function) { if (function.isEmpty()) { return; } // 清除之前绘制的图像 _scene->clear(); // 设置画笔 QPen pen(Qt::blue); pen.setWidth(2); // 计算函数图像的点 QVector<QPointF> points; double xMin = -10.0, xMax = 10.0, xStep = 0.1; double yMin = -10.0, yMax = 10.0, yStep = 0.1; for (double x = xMin; x <= xMax; x += xStep) { double y = calculateFunction(function, x); if (y >= yMin && y <= yMax) { points.append(QPointF(x, y)); } } // 绘制函数图像 QPainter painter; painter.begin(&_pixmap); painter.setPen(pen); for (int i = 1; i < points.size(); ++i) { painter.drawLine(mapToPixmap(points[i - 1]), mapToPixmap(points[i])); } painter.end(); // 将绘制的图像添加到QGraphicsScene中 _scene->addPixmap(_pixmap); // 更新QGraphicsView显示出来 ui->graphicsView->viewport()->update(); } ``` 其中,calculateFunction函数用于计算函数的值: ``` double FunctionPlotter::calculateFunction(const QString &function, double x) { // 使用QJSEngine计算函数的值 QJSEngine engine; QJSValue result = engine.evaluate(QString("function(x) { return %1; }(x)").arg(function)); if (result.isError()) { qWarning() << "Failed to evaluate function:" << result.toString(); return NAN; } return result.toNumber(); } ``` mapToPixmap函数用于将坐标系中的点映射到QGraphicsPixmapItem中的坐标: ``` QPointF FunctionPlotter::mapToPixmap(const QPointF &point) { // 将坐标系中的点映射到QGraphicsPixmapItem中的坐标 QRectF rect = ui->graphicsView->sceneRect(); double x = (point.x() - rect.left()) / rect.width() * _pixmap.width(); double y = (rect.bottom() - point.y()) / rect.height() * _pixmap.height(); return QPointF(x, y); } ``` 4. 连接信号和槽 将QPushButton的clicked信号连接到绘制函数的槽函数drawFunction中: ``` void FunctionPlotter::on_pushButton_clicked() { QString function = ui->lineEdit->text(); drawFunction(function); } ``` 将清除图像的QPushButton的clicked信号连接到清除图像的槽函数clearFunction中: ``` void FunctionPlotter::on_pushButton_2_clicked() { // 清除所有函数图像 _scene->clear(); _pixmap.fill(Qt::transparent); } ``` 将保存图像的QPushButton的clicked信号连接到保存图像的槽函数saveFunction中: ``` void FunctionPlotter::on_pushButton_3_clicked() { // 弹出文件对话框选择保存文件路径 QString fileName = QFileDialog::getSaveFileName(this, tr("Save Image"), ".", tr("JPEG Image (*.jpg)")); if (!fileName.isEmpty()) { _pixmap.save(fileName, "JPEG"); } } ``` 5. 完成 到此,我们的函数图像绘制器就完成了。您可以在输入框中输入任意函数,点击设置好的“绘制”按钮,绘制出该函数图像,并在坐标轴中呈现出来。您可以叠加多个函数图像,使用“清除”按钮可以清除之前生成的所有函数图像,使用“保存”按钮可以保存当前的函数图像并且可以选择保存地址,转化为jpg图片文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值