QT:Graphics View的坐标系介绍

在 Qt 的 Graphics View 框架中,存在三种不同的坐标系,分别是 物品坐标系(Item Coordinates)、场景坐标系(Scene Coordinates) 和 视图坐标系(View Coordinates)。这三种坐标系在图形的绘制、定位和交互中起着关键作用,

物品坐标系(Item Coordinates)

定义:物品坐标系是每个 QGraphicsItem 自身的本地坐标系。物品的位置、大小和形状都是基于这个坐标系来定义的。物品坐标系的原点通常位于物品的左上角(对于大多数标准图形项),X 轴向右为正,Y 轴向下为正。
特点:
物品在自身坐标系中的位置是相对固定的,不依赖于其在场景中的位置。
当对物品进行变换(如平移、旋转、缩放)时,这些变换都是在物品坐标系中进行的。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QPainter>
#include <QPen>
#include <QFont>

// 自定义可绘制坐标系的矩形图形项类
class CoordinateRectItem : public QGraphicsRectItem {
public:
    CoordinateRectItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = nullptr)
        : QGraphicsRectItem(x, y, width, height, parent) {}

protected:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
        // 先调用基类的 paint 方法绘制矩形
        QGraphicsRectItem::paint(painter, option, widget);

        // 设置画笔和字体
        QPen pen(Qt::red);
        painter->setPen(pen);
        QFont font;
        font.setPointSize(8);
        painter->setFont(font);

        // 绘制 X 轴
        painter->drawLine(rect().left(), rect().top(), rect().right(), rect().top());
        // 绘制 X 轴刻度和标签
        for (int i = 0; i <= rect().width(); i += 20) {
            painter->drawLine(rect().left() + i, rect().top(), rect().left() + i, rect().top() + 5);
            painter->drawText(rect().left() + i - 5, rect().top() - 5, QString::number(i));
        }

        // 绘制 Y 轴
        painter->drawLine(rect().left(), rect().top(), rect().left(), rect().bottom());
        // 绘制 Y 轴刻度和标签
        for (int i = 0; i <= rect().height(); i += 20) {
            painter->drawLine(rect().left(), rect().top() + i, rect().left() + 5, rect().top() + i);
            painter->drawText(rect().left() - 20, rect().top() + i + 5, QString::number(i));
        }
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 创建场景
    QGraphicsScene scene;

    // 创建不旋转的矩形图形项
    CoordinateRectItem *nonRotatedRectItem = new CoordinateRectItem(0, 0, 100, 50);
    // 设置不旋转矩形的位置,避免与旋转矩形重叠
    nonRotatedRectItem->setPos(20, 20);
    // 让 nonRotatedRectItem 也旋转 60 度
    nonRotatedRectItem->setRotation(60);
    scene.addItem(nonRotatedRectItem);

    // 创建不旋转的矩形图形项
    CoordinateRectItem *nonRotatedRectItem1 = new CoordinateRectItem(0, 0, 100, 50);
    // 设置不旋转矩形的位置,避免与旋转矩形重叠
    nonRotatedRectItem1->setPos(20, 20);
    scene.addItem(nonRotatedRectItem1);

    // 创建视图
    QGraphicsView view(&scene);
    view.setWindowTitle("Two Rotated Rectangles with Coordinates");
    view.resize(400, 300);
    view.show();

    return app.exec();
}

QApplication:用于管理 Qt 应用程序的资源和事件循环。
QGraphicsScene:表示一个图形场景,用于管理和组织 QGraphicsItem 对象。
QGraphicsView:用于显示 QGraphicsScene 中的内容。
QGraphicsRectItem:表示一个矩形图形项。
QPainter:用于在图形项上进行绘制操作。
QPen:用于设置绘制线条的属性,如颜色、宽度等。
QFont:用于设置绘制文本的字体属性。
CoordinateRectItem :
继承自 QGraphicsRectItem,重写了 paint 方法。
paint 方法的实现步骤如下:
调用基类的 paint 方法绘制矩形。
设置画笔颜色为红色,字体大小为 8 号。
绘制 X 轴和 Y 轴。
以 20 为间隔绘制 X 轴和 Y 轴的刻度,并在刻度旁边绘制对应的坐标值。
创建 QApplication 对象,启动应用程序的事件循环。
创建 QGraphicsScene 对象,用于管理图形项。
创建第一个 CoordinateRectItem 对象 nonRotatedRectItem,设置其位置为 (20, 20),并将其旋转 60 度,然后添加到场景中。
创建第二个 CoordinateRectItem 对象 nonRotatedRectItem1,设置其位置为 (20, 20),不进行旋转操作,直接添加到场景中。
创建 QGraphicsView 对象,关联场景,设置窗口标题和大小,最后显示视图。

在这里插入图片描述

在一个图形场景中展示两个矩形,其中一个矩形旋转了 60 度,并且每个矩形内部都绘制了物品坐标系的坐标轴、刻度和标签,方便用户观察矩形的旋转效果和物品坐标系的情况。

场景坐标系(Scene Coordinates)

定义:场景坐标系是整个 QGraphicsScene 的全局坐标系。场景中的所有物品都通过其在场景坐标系中的位置来定位。场景坐标系的原点通常位于场景的左上角,X 轴向右为正,Y 轴向下为正。
特点:
场景坐标系是物品坐标系和视图坐标系之间的桥梁,物品在场景中的位置可以通过其在场景坐标系中的坐标来确定。
场景可以包含多个物品,每个物品在场景坐标系中都有唯一的位置。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QGraphicsTextItem>
#include <QPainter>
#include <QPen>
#include <QFont>

// 自定义用于绘制场景坐标系的图形项
class SceneCoordinateItem : public QGraphicsItem {
public:
    SceneCoordinateItem(QGraphicsItem *parent = nullptr) : QGraphicsItem(parent) {}

    // 定义图形项的边界矩形
    QRectF boundingRect() const override {
        // 这里简单设置一个较大的边界矩形,以覆盖可能的场景范围
        return QRectF(-300, -300, 600, 600);
    }

    // 绘制场景坐标系
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
        Q_UNUSED(option);
        Q_UNUSED(widget);

        // 设置画笔
        QPen pen(Qt::black);
        pen.setWidth(2);
        painter->setPen(pen);

        // 设置字体
        QFont font;
        font.setPointSize(10);
        painter->setFont(font);

        // 绘制 X 轴
        painter->drawLine(-1000, 0, 1000, 0);
        // 绘制 X 轴箭头
        painter->drawLine(980, 10, 1000, 0);
        painter->drawLine(980, -10, 1000, 0);
        // 绘制 X 轴刻度和标签
        for (int i = -1000; i <= 1000; i += 100) {
            painter->drawLine(i, -5, i, 5);
            QString label = QString::number(i);
            painter->drawText(i - 10, 20, label);
        }

        // 绘制 Y 轴
        painter->drawLine(0, -1000, 0, 1000);
        // 绘制 Y 轴箭头
        painter->drawLine(-10, 980, 0, 1000);
        painter->drawLine(10, 980, 0, 1000);
        // 绘制 Y 轴刻度和标签
        for (int i = -1000; i <= 1000; i += 100) {
            painter->drawLine(-5, i, 5, i);
            QString label = QString::number(i);
            painter->drawText(-30, i + 5, label);
        }
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QGraphicsScene scene;

    QGraphicsRectItem *originalRectItem = new QGraphicsRectItem(0, 0, 100, 50);
    QPointF originalPos = QPointF(50, 50);  // 记录矩形的原始位置
    originalRectItem->setPos(originalPos);
    scene.addItem(originalRectItem);

    // 为原始矩形添加标记
    QGraphicsTextItem *originalLabel = new QGraphicsTextItem("Original");
    originalLabel->setPos(originalPos.x(), originalPos.y() - 20);
    scene.addItem(originalLabel);

    // 创建旋转后的矩形
    QGraphicsRectItem *rotatedRectItem = new QGraphicsRectItem(0, 0, 100, 50);

    // 以场景坐标系原点为中心旋转矩形 90 度
    // 先将矩形移动到场景原点
    rotatedRectItem->setPos(0, 0);
    rotatedRectItem->setRotation(90);
    // 计算旋转后的位置
    QTransform transform;
    transform.rotate(90);
    QPointF newPos = transform.map(originalPos);
    rotatedRectItem->setPos(newPos);
    scene.addItem(rotatedRectItem);

    // 为旋转后的矩形添加标记
    QGraphicsTextItem *rotatedLabel = new QGraphicsTextItem("Rotated");
    rotatedLabel->setPos(newPos.x(), newPos.y() - 20);
    scene.addItem(rotatedLabel);

    // 创建并添加场景坐标系图形项
    SceneCoordinateItem *coordinateItem = new SceneCoordinateItem();
    scene.addItem(coordinateItem);

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

在这里插入图片描述

保留原始矩形:
创建 originalRectItem 表示原始矩形,并将其添加到场景中。
使用 QGraphicsTextItem 创建 originalLabel 作为原始矩形的标记,设置其位置在原始矩形上方,并添加到场景中。
创建旋转后的矩形:
创建 rotatedRectItem 作为旋转后的矩形。
对 rotatedRectItem 进行旋转操作,先将其移动到场景原点,旋转 90 度,再计算并设置旋转后的位置。
使用 QGraphicsTextItem 创建 rotatedLabel 作为旋转后矩形的标记,设置其位置在旋转后矩形上方,并添加到场景中。
绘制场景坐标系:
创建 SceneCoordinateItem 对象 coordinateItem 并添加到场景中,用于绘制场景坐标系。
显示视图:
创建 QGraphicsView 对象 view 并关联场景,最后显示视图。

视图坐标系(View Coordinates)

定义:视图坐标系是 QGraphicsView 窗口的坐标系。视图坐标系的原点位于视图窗口的左上角,X 轴向右为正,Y 轴向下为正。视图坐标系的单位是像素。
特点:
视图坐标系用于确定用户在视图窗口中看到的内容,它与场景坐标系之间通过视图的变换矩阵进行映射。
视图可以对场景进行缩放、平移、旋转等操作,这些操作会改变视图坐标系和场景坐标系之间的映射关系。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QGraphicsTextItem>
#include <QPainter>
#include <QPen>
#include <QFont>

// 自定义用于绘制视图坐标系的图形项
class ViewCoordinateItem : public QGraphicsItem {
public:
    ViewCoordinateItem(QGraphicsView* view, QGraphicsItem *parent = nullptr) : QGraphicsItem(parent), view(view) {}

    // 定义图形项的边界矩形
    QRectF boundingRect() const override {
        // 根据视图大小设置边界矩形
        QSize size = view->size();
        return QRectF(0, 0, size.width(), size.height());
    }

    // 绘制视图坐标系
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
        Q_UNUSED(option);
        Q_UNUSED(widget);

        // 设置画笔
        QPen pen(Qt::red);
        pen.setWidth(2);
        painter->setPen(pen);

        // 设置字体
        QFont font;
        font.setPointSize(10);
        painter->setFont(font);

        // 获取视图大小
        QSize size = view->size();

        // 绘制 X 轴
        painter->drawLine(0, size.height() / 2, size.width(), size.height() / 2);
        // 绘制 X 轴箭头
        painter->drawLine(size.width() - 20, size.height() / 2 - 10, size.width(), size.height() / 2);
        painter->drawLine(size.width() - 20, size.height() / 2 + 10, size.width(), size.height() / 2);
        // 绘制 X 轴刻度和标签
        for (int i = 0; i <= size.width(); i += 50) {
            painter->drawLine(i, size.height() / 2 - 5, i, size.height() / 2 + 5);
            QString label = QString::number(i);
            painter->drawText(i - 10, size.height() / 2 + 20, label);
        }

        // 绘制 Y 轴
        painter->drawLine(size.width() / 2, 0, size.width() / 2, size.height());
        // 绘制 Y 轴箭头
        painter->drawLine(size.width() / 2 - 10, size.height() - 20, size.width() / 2, size.height());
        painter->drawLine(size.width() / 2 + 10, size.height() - 20, size.width() / 2, size.height());
        // 绘制 Y 轴刻度和标签
        for (int i = 0; i <= size.height(); i += 50) {
            painter->drawLine(size.width() / 2 - 5, i, size.width() / 2 + 5, i);
            QString label = QString::number(i);
            painter->drawText(size.width() / 2 - 30, i + 5, label);
        }
    }

private:
    QGraphicsView* view;
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QGraphicsScene scene;
    // 设置场景范围小于视图,例如设置场景大小为 300x500
    scene.setSceneRect(0, 0, 300, 500);

    // 创建原始矩形框
    QGraphicsRectItem *originalRectItem = new QGraphicsRectItem(10, 10, 100, 50);
    originalRectItem->setPos(50, 50);
    scene.addItem(originalRectItem);

    // 为原始矩形框添加标记
    QGraphicsTextItem *originalLabel = new QGraphicsTextItem("Original Rect");
    originalLabel->setPos(originalRectItem->pos().x(), originalRectItem->pos().y() - 20);
    scene.addItem(originalLabel);

    // 创建平移后的矩形框
    QGraphicsRectItem *translatedRectItem = new QGraphicsRectItem(10, 10, 100, 50);
    // 将矩形框向左平移 120 个单位
    translatedRectItem->setPos(50 - 120, 50);
    scene.addItem(translatedRectItem);

    // 为平移后的矩形框添加标记
    QGraphicsTextItem *translatedLabel = new QGraphicsTextItem("Translated Rect");
    translatedLabel->setPos(translatedRectItem->pos().x(), translatedRectItem->pos().y() - 20);
    scene.addItem(translatedLabel);

    QGraphicsView view(&scene);
    // 对视图进行缩放操作
    view.scale(2.0, 2.0);

    // 创建并添加视图坐标系图形项
    ViewCoordinateItem *coordinateItem = new ViewCoordinateItem(&view);
    scene.addItem(coordinateItem);
    view.resize(400, 600);
    view.show();

    return app.exec();
}

在这里插入图片描述

坐标系之间的转换

在 Graphics View 框架中,可以使用以下方法进行坐标系之间的转换:
物品坐标系和场景坐标系之间的转换:
QGraphicsItem::mapToScene(const QPointF &point):将物品坐标系中的点转换为场景坐标系中的点。
QGraphicsItem::mapFromScene(const QPointF &point):将场景坐标系中的点转换为物品坐标系中的点。
场景坐标系和视图坐标系之间的转换:
QGraphicsView::mapToScene(const QPoint &point):将视图坐标系中的点转换为场景坐标系中的点。
QGraphicsView::mapFromScene(const QPointF &point):将场景坐标系中的点转换为视图坐标系中的点。

QGraphicsItem::mapToScene

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QGraphicsTextItem>
#include <QDebug>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 创建场景
    QGraphicsScene scene;

    // 创建一个矩形图形项
    QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 100, 50);
    // 设置矩形在场景中的位置
    rectItem->setPos(50, 50);
    scene.addItem(rectItem);

    // 在物品坐标系中定义一个点
    QPointF itemPoint(20, 30);

    // 将物品坐标系中的点转换为场景坐标系中的点
    QPointF scenePoint = rectItem->mapToScene(itemPoint);

    // 输出转换后的场景坐标
    qDebug() << "Item Coordinate: (" << itemPoint.x() << ", " << itemPoint.y() << ")";
    qDebug() << "Scene Coordinate: (" << scenePoint.x() << ", " << scenePoint.y() << ")";

    // 创建一个文本图形项来显示场景坐标
    QGraphicsTextItem *textItem = new QGraphicsTextItem(QString("Scene Point: (%1, %2)").arg(scenePoint.x()).arg(scenePoint.y()));
    textItem->setPos(scenePoint);
    scene.addItem(textItem);

    // 创建视图
    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

在这里插入图片描述

QGraphicsItem::mapFromScene

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QGraphicsTextItem>
#include <QDebug>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 创建场景
    QGraphicsScene scene;

    // 创建一个矩形图形项
    QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 100, 50);
    // 设置矩形在场景中的位置
    rectItem->setPos(50, 50);
    scene.addItem(rectItem);

    // 在场景坐标系中定义一个点
    QPointF scenePoint(80, 70);

    // 将场景坐标系中的点转换为物品坐标系中的点
    QPointF itemPoint = rectItem->mapFromScene(scenePoint);

    // 输出转换后的物品坐标
    qDebug() << "Scene Coordinate: (" << scenePoint.x() << ", " << scenePoint.y() << ")";
    qDebug() << "Item Coordinate: (" << itemPoint.x() << ", " << itemPoint.y() << ")";

    // 创建一个文本图形项来显示物品坐标,并将矩形作为其父项
    QGraphicsTextItem *textItem = new QGraphicsTextItem(QString("Item Point: (%1, %2)").arg(itemPoint.x()).arg(itemPoint.y()), rectItem);
    textItem->setPos(itemPoint);

    // 创建视图
    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

在这里插入图片描述

QGraphicsView::mapToScene

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QDebug>

// 自定义的 QGraphicsView 类,用于处理鼠标点击事件
class CustomGraphicsView : public QGraphicsView {
public:
    CustomGraphicsView(QGraphicsScene *scene, QWidget *parent = nullptr)
        : QGraphicsView(scene, parent) {}

protected:
    // 重写鼠标按下事件处理函数
    void mousePressEvent(QMouseEvent *event) override {
        // 获取鼠标在视图中的位置
        QPoint viewPos = event->pos();
        // 使用 mapToScene 函数将视图坐标转换为场景坐标
        QPointF scenePos = mapToScene(viewPos);

        qDebug() << "View Position: " << viewPos;
        qDebug() << "Scene Position: " << scenePos;

        QGraphicsView::mousePressEvent(event);
    }
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    // 创建一个 QGraphicsScene
    QGraphicsScene scene;
    // 在场景中添加一个矩形,方便可视化
    scene.addRect(10, 10, 200, 200);

    // 创建自定义的 QGraphicsView,并将场景设置给它
    CustomGraphicsView view(&scene);
    view.setScene(&scene);
    view.resize(500,500);
    view.show();

    return a.exec();
}

#include :引入 QApplication 类,它是 Qt 应用程序的核心类,负责管理应用程序的资源和事件循环,每个 Qt GUI 应用程序都必须有且仅有一个 QApplication 对象。
#include :引入 QGraphicsView 类,它是一个用于显示 QGraphicsScene 内容的部件,提供了视图的滚动、缩放等功能。
#include :引入 QGraphicsScene 类,它是一个用于管理和组织图形项(如矩形、椭圆等)的容器,提供了图形项的添加、删除、查找等操作。
#include :引入 QMouseEvent 类,它用于处理鼠标事件,例如鼠标按下、释放、移动等。
#include :引入 QDebug 类,它用于在调试时输出信息,方便开发者查看程序的运行状态。
class CustomGraphicsView : public QGraphicsView 表示 CustomGraphicsView 类继承自 QGraphicsView 类,这样 CustomGraphicsView 就拥有了 QGraphicsView 的所有功能,并且可以对其进行扩展。

void mousePressEvent(QMouseEvent *event) override 重写了 QGraphicsView 的 mousePressEvent 函数,用于处理鼠标按下事件。
QPoint viewPos = event->pos(); 获取鼠标在视图中的位置,event->pos() 返回一个 QPoint 对象,表示鼠标相对于视图窗口的坐标。
QPointF scenePos = mapToScene(viewPos); 使用 mapToScene 函数将视图坐标转换为场景坐标,mapToScene 是 QGraphicsView 提供的一个成员函数,用于将视图坐标系中的点映射到场景坐标系中。
qDebug() << "View Position: " << viewPos; 和 qDebug() << "Scene Position: " << scenePos; 使用 qDebug 输出鼠标在视图和场景中的坐标,方便调试。
QGraphicsView::mousePressEvent(event); 调用基类的 mousePressEvent 函数,确保基类的默认处理逻辑也能正常执行

QApplication a(argc, argv); 创建一个 QApplication 对象,用于管理应用程序的资源和事件循环。
QGraphicsScene scene; 创建一个 QGraphicsScene 对象,用于管理图形项。
scene.addRect(10, 10, 200, 200); 在场景中添加一个矩形,矩形的左上角坐标为 (10, 10),宽度为 200,高度为 200,这样可以方便我们可视化场景的内容。
CustomGraphicsView view(&scene); 创建一个 CustomGraphicsView 对象,并将之前创建的 QGraphicsScene 对象的指针传递给它。
view.setScene(&scene); 将 QGraphicsScene 对象设置给 CustomGraphicsView,这样 CustomGraphicsView 就可以显示 QGraphicsScene 中的内容。
view.resize(500,500); 将 CustomGraphicsView 的大小调整为 500x500 像素。
view.show(); 显示 CustomGraphicsView 窗口。
return a.exec(); 启动应用程序的事件循环,程序会一直运行,直到用户关闭窗口或调用 QApplication::quit() 函数。

在这里插入图片描述
创建一个带有自定义鼠标点击事件处理的 QGraphicsView 窗口,显示一个 QGraphicsScene 中的矩形,并在鼠标点击时输出鼠标在视图和场景中的坐标。

QGraphicsView::mapFromScene

函数用于将场景坐标系中的点映射到视图坐标系中。

自定义 CustomGraphicsView 类
继承 QGraphicsView:通过继承 QGraphicsView 类,并重写 mouseMoveEvent 函数来处理鼠标移动事件。
mouseMoveEvent 函数:
QPoint viewPos = event->pos();:获取鼠标在视图中的原始位置。
QPointF scenePos = mapToScene(viewPos);:使用 mapToScene 函数将视图坐标转换为场景坐标。
QPoint convertedViewPos = mapFromScene(scenePos);:使用 mapFromScene 函数将场景坐标转换回视图坐标。
使用 qDebug 输出原始视图坐标、场景坐标以及转换后的视图坐标,方便调试查看。
2. main 函数
创建 QApplication 对象,用于管理应用程序的事件循环。
创建 QGraphicsScene 对象,并添加一个矩形到场景中,方便可视化。
创建 CustomGraphicsView 对象,将场景设置给它,并调整大小和显示。
view.setMouseTracking(true);:启用鼠标跟踪,这样即使鼠标按钮未按下,移动鼠标时也会触发 mouseMoveEvent 函数。

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QDebug>

// 自定义的 QGraphicsView 类,用于处理鼠标移动事件
class CustomGraphicsView : public QGraphicsView {
public:
    CustomGraphicsView(QGraphicsScene *scene, QWidget *parent = nullptr)
        : QGraphicsView(scene, parent) {}

protected:
    // 重写鼠标移动事件处理函数
    void mouseMoveEvent(QMouseEvent *event) override {
        // 获取鼠标在视图中的位置
        QPoint viewPos = event->pos();

        // 使用 mapToScene 函数将视图坐标转换为场景坐标
        QPointF scenePos = mapToScene(viewPos);

        // 使用 mapFromScene 函数将场景坐标转换回视图坐标
        QPoint convertedViewPos = mapFromScene(scenePos);

        qDebug() << "Original View Position: " << viewPos;
        qDebug() << "Scene Position: " << scenePos;
        qDebug() << "Converted View Position: " << convertedViewPos;

        QGraphicsView::mouseMoveEvent(event);
    }
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    // 创建一个 QGraphicsScene
    QGraphicsScene scene;
    // 在场景中添加一个矩形,方便可视化
    scene.addRect(10, 10, 200, 200);

    // 创建自定义的 QGraphicsView,并将场景设置给它
    CustomGraphicsView view(&scene);
    view.setScene(&scene);
    view.resize(500, 500);
    view.show();

    // 启用鼠标跟踪,这样才能触发 mouseMoveEvent
    view.setMouseTracking(true);

    return a.exec();
}

在这里插入图片描述

使用 Qt 编译器进行编译和运行。运行程序后,当你移动鼠标时,控制台会输出鼠标在视图和场景中的坐标,以及从场景坐标转换回的视图坐标。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/978212.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

医院HIS接入大模型:算力基础设施与训练能力的深度剖析与测算

一、引言 1.1 研究背景与意义 在数字化医疗快速发展的当下,医院信息系统(Hospital Information System,HIS)作为医疗信息化的核心枢纽,承载着患者诊疗信息、医院运营管理等关键数据 ,对提升医疗服务质量、优化医院管理流程起着至关重要的作用。然而,传统 HIS 在面对日…

入门网络安全工程师要学习哪些内容【2025年寒假最新学习计划】

&#x1f91f; 基于入门网络安全/黑客打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 大家都知道网络安全行业很火&#xff0c;这个行业因为国家政策趋势正在大力发展&#xff0c;大有可为!但很多人对网络安全工程师还是不了解&#xff0c;不知道网…

阿里云CDN转https个人测试证书过期更换

网站是http的虚拟主机&#xff0c;微信小程序要求https&#xff0c;所以申请了阿里云CDN和个人测试证书&#xff08;以前叫免费证书&#xff09;&#xff0c;把http转成https。 但是个人测试证书只有三个月有效期&#xff0c;所以每隔三个月要手动申请更换一次。 在阿里云CDN…

东信营销科技巨额补贴仍由盈转亏:毛利率大幅下滑,现金流告急

《港湾商业观察》施子夫 近期&#xff0c;东信营销科技有限公司&#xff08;以下简称&#xff0c;东信营销科技&#xff09;递表港交所&#xff0c;联席保荐机构为海通国际和中银国际。 东信营销科技的国内运营主体为深圳市东信时代信息技术有限公司。尽管期内收入规模有所提…

AOP进阶-04.切入点表达式-@annotation

一.annotation注解 我们在最后一个切入点表达式中要匹配多个无规则的方法&#xff0c;这样的写法有些冗余了。而annotation注解就是来解决这一问题的。 annotation注解使用特定的注解来匹配方法。我们首先自定义一个注解&#xff0c;该注解就相当于一个标签&#xff0c;目标对…

特斯拉 FSD 算法深度剖析:软件层面全解读

一、引言 特斯拉的 FSD&#xff08;Full Self-Driving&#xff09;系统作为自动驾驶领域的前沿成果&#xff0c;其软件层面的算法设计至关重要。本文将从软件的角度&#xff0c;深入探讨特斯拉 FSD 所采用的算法&#xff0c;包括感知、规划、控制等多个方面&#xff0c;以期为…

LabVIEW同步数据采集功能

VI通过使用数据采集&#xff08;DAQ&#xff09;硬件系统&#xff0c;进行多通道同步采集&#xff0c;实时获取模拟信号数据。它利用外部时钟信号触发数据采集&#xff0c;支持连续采样模式&#xff0c;并将采集到的数据实时显示在波形图上&#xff0c;方便用户进行数据监控和分…

YOLOv12 ——基于卷积神经网络的快速推理速度与注意力机制带来的增强性能结合

概述 实时目标检测对于许多实际应用来说已经变得至关重要&#xff0c;而Ultralytics公司开发的YOLO&#xff08;You Only Look Once&#xff0c;只看一次&#xff09;系列一直是最先进的模型系列&#xff0c;在速度和准确性之间提供了稳健的平衡。注意力机制的低效阻碍了它们在…

Ubuntu20.04之VNC的安装使用与常见问题

Ubuntu20.04之VNC的安装与使用 安装图形桌面选择安装gnome桌面选择安装xface桌面 VNC-Server安装配置开机自启 VNC Clientroot用户无法登入问题临时方案永久方案 安装图形桌面 Ubuntu20.04主流的图形桌面有gnome和xface两种&#xff0c;两种桌面的安装方式我都会写&#xff0c…

14.二叉搜索树

二叉搜索树 1.概念 ⼆叉搜索树⼜称⼆叉排序树&#xff0c;它或者是⼀棵空树&#xff0c;或者是具有以下性质的⼆叉树: *若它的左⼦树不为空&#xff0c;则左⼦树上所有结点的值都⼩于等于根结点的值 *若它的右⼦树不为空&#xff0c;则右⼦树上所有结点的值都⼤于等于根结点…

web网络安全---cookie篇

什么是Cookie 由于HTTP是一种无状态的协议&#xff0c;服务器单从网络连接上无从知道客户身份。怎么办呢&#xff1f;就给客户端们颁发一个通行证吧&#xff0c;每人一个&#xff0c;无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的…

Qt 开源音视频框架模块之QtAV播放器实践

Qt 开源音视频框架模块QtAV播放器实践 1 摘要 QtAV是一个基于Qt的多媒体框架&#xff0c;旨在简化音视频播放和处理。它是一个跨平台的库&#xff0c;支持多种音视频格式&#xff0c;并提供了一个简单易用的API来集成音视频功能。QtAV的设计目标是为Qt应用程序提供强大的音视…

WPF学习之Prism(二)

前言 学习一下Prism。 1.Prism Prism框架提供了一套丰富的工具、类和模块&#xff0c;帮助开发人员实现以下功能&#xff1a; 模块化&#xff1a;Prism框架支持将应用程序拆分为多个模块&#xff0c;每个模块具有自己的功能和视图。这种模块化的设计使得应用程序更加灵活和…

前端实现rsa加密功能

本文将从web和小程序两个端来实现rsa的加密功能。 一般项目的登录密码、身份证号以及一些用户敏感信息等在传输的时候需要使用加密传输&#xff0c;一般来说&#xff0c;前端只会得到后端给的公钥&#xff0c;而rsa加密&#xff0c;可以用公钥加密&#xff0c;也可以用私钥加密…

VidSketch:具有扩散控制的手绘草图驱动视频生成

浙大提出的VidSketch是第一个能够仅通过任意数量的手绘草图和简单的文本提示来生成高质量视频动画的应用程序。该方法训练是在单个 RTX4090 GPU 上进行的&#xff0c;针对每个动作类别使用一个小型、高质量的数据集。VidSketch方法使所有用户都能使用简洁的文本提示和直观的手绘…

STM32——HAL库开发笔记23(定时器4—输入捕获)(参考来源:b站铁头山羊)

定时器有四个通道&#xff0c;这些通道既可以用来作为输入&#xff0c;又可以作为输出。做输入的时候&#xff0c;可以使用定时器对外部输入的信号的时间参数进行测量&#xff1b;做输出的时候&#xff0c;可以使用定时器向外输出精确定时的方波信号。 一、输入捕获 的基本原理…

Jquery详解

一.Jquery介绍 1.jQuery 是一个快速、简洁的 JavaScript 库&#xff0c;它极大地简化了 HTML 文档遍历、事件处理、动画效果和 AJAX 交互等操作&#xff0c;使开发者能够更轻松地创建动态和交互性强的网页。对原生js的封装,提供了很多时间,调用Api即可,并且对浏览器做了兼容性…

【EB-06】SystemCreator dbc转arxml

SystemCreator dbc转arxml 1. SystemCreator 意义2. SystemCreator使用方法2.1 实现步骤2.2 参考官方文档方法1. SystemCreator 意义 EB Tresos 对dbc直接导入的支持不是很完善,dbc也不是AUTOSAR标准的数据库文件,EB建议所有通信矩阵通过ARXML交互比较合理(AUTOSAR定义的)…

LeetCode225.用队列实现栈

LeetCode225.用队列实现栈 文章目录 LeetCode225.用队列实现栈题目描述实现1:实现2: 题目描述 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 实现 MyStack…

【Linux】vim 设置

【Linux】vim 设置 零、起因 刚学Linux&#xff0c;有时候会重装Linux系统&#xff0c;然后默认的vi不太好用&#xff0c;需要进行一些设置&#xff0c;本文简述如何配置一个好用的vim。 壹、软件安装 sudo apt-get install vim贰、配置路径 对所有用户生效&#xff1a; …