当前位置: 首页 > news >正文

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;// 设置场景范围小于视图,例如设置场景大小为 300x500scene.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);// 创建一个 QGraphicsSceneQGraphicsScene 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);// 创建一个 QGraphicsSceneQGraphicsScene scene;// 在场景中添加一个矩形,方便可视化scene.addRect(10, 10, 200, 200);// 创建自定义的 QGraphicsView,并将场景设置给它CustomGraphicsView view(&scene);view.setScene(&scene);view.resize(500, 500);view.show();// 启用鼠标跟踪,这样才能触发 mouseMoveEventview.setMouseTracking(true);return a.exec();
}

在这里插入图片描述

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

相关文章:

QT:Graphics View的坐标系介绍

在 Qt 的 Graphics View 框架中&#xff0c;存在三种不同的坐标系&#xff0c;分别是 物品坐标系&#xff08;Item Coordinates&#xff09;、场景坐标系&#xff08;Scene Coordinates&#xff09; 和 视图坐标系&#xff08;View Coordinates&#xff09;。这三种坐标系在图形…...

530 Login fail. A secure connection is requiered(such as ssl)-java发送QQ邮箱(简单配置)

由于cs的csdN许多文章关于这方面的都是vip文章&#xff0c;而本文是免费的&#xff0c;希望广大网友觉得有帮助的可以多点赞和关注&#xff01; QQ邮箱授权码到这里去开启 授权码是16位的字母&#xff0c;填入下面的mail.setting里面的pass里面 # 邮件服务器的SMTP地址 host…...

vs2015下使用openmp

一 OPENMP 简介 OpenMP(Open Multi-Processing)是一个基于共享内存的并行编程API,通过编译器指令实现多线程并行开发。其核心特性包括: 1)通过简单的#pragma指令实现并行化 2)支持增量并行(逐步优化代码) 3)跨平台(Windows/Linux/macOS) 4)支持C/C++/Fortra …...

Docker 搭建 Gitlab 服务器 (完整详细版)

参考 Docker 搭建 Gitlab 服务器 (完整详细版)_docker gitlab-CSDN博客 Docker 安装 (完整详细版)_docker安装-CSDN博客 Docker 日常命令大全(完整详细版)_docker命令-CSDN博客 1、Gitlab镜像 # 查找Gitlab镜像 docker search gitlab # 拉取Gitlab镜像 docker pull gitlab/g…...

【万字长文】开源之播对话白鲸开源CEO郭炜--乐观主义的开源精神走得更远

本文为白鲸开源科技CEO郭炜1小时深度访谈全记录 来源于&#xff1a;开源之播」Episode15:对话郭炜–乐观主义的开源精神走得更远 大家好&#xff0c;我是郭炜&#xff0c;开源圈的“郭大侠”。作为 Apache 基金会的成员&#xff0c;我曾参与并孵化了多个开源项目&#xff0c;如…...

机试刷题_674. 最长连续递增序列【python】

674. 最长连续递增序列 class Solution:def findLengthOfLCIS(self, nums: List[int]) -> int:if not nums:return 0if len(nums)1:return 1left 0right len(nums)-1tmp []tmp.append(nums[0])res 0while left<right:if nums[left]<nums[left1]:tmp.append(nums[l…...

ipe网络安全

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 什么是IDS&#xff1f; IDS是英文"Intrusion Detection Systems"的缩写&#xff0c;中文意思是"入侵检测系统"。 大家还记得「网络安全」安…...

QT:QPen、QBrush、与图形抗锯齿的关联

QPen QPen 是 Qt 框架中用于定义绘图时使用的画笔属性的类。在使用 QPainter 进行 2D 绘图时&#xff0c;QPen 可以控制线条的外观&#xff0c;比如线条的颜色、宽度、样式&#xff08;如实线、虚线等&#xff09;、端点样式&#xff08;如方形端点、圆形端点等&#xff09;和…...

android keystore源码分析

架构 Android Keystore API 和底层 Keymaster HAL 提供了一套基本的但足以满足需求的加密基元&#xff0c;以便使用访问受控且由硬件支持的密钥实现相关协议。 Keymaster HAL 是由原始设备制造商 (OEM) 提供的动态加载库&#xff0c;密钥库服务使用它来提供由硬件支持的加密服…...

【12】智能合约开发入门

12-1 在线合约开发 Cloud IDE简介 基本框架 Cloud IDE是BaaS合约平台提供的在线合约开发工具 IDE是一个去中心化应用&#xff08;Dapp&#xff09;&#xff0c;通过JavaScript SDK直接与区块链平台通信&#xff0c;进行合约部署和调用 核心功能 合约工程管理 合约编辑与编…...

web安全——分析应用程序

文章目录 一、确定用户输入入口点二、确定服务端技术三、解析受攻击面 一、确定用户输入入口点 在检查枚举应用程序功能时生成的HTTP请求的过程中&#xff0c;用户输入入口点包括&#xff1a; URL文件路径 通常&#xff0c;在查询字符?之前的URL部分并不视为用户输入入口&am…...

Wpf 之Generic.xaml

在 WPF 中&#xff0c;Generic.xaml 是一个特殊的资源文件&#xff0c;它会被自动加载&#xff0c;不需要显式添加。这是 WPF 的命名约定。当 WPF 初始化自定义控件时&#xff0c;它会专门查找这个名字的文件。 这个名字是硬编码在 WPF 框架中的&#xff0c;不能改变。 Generi…...

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

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

解锁C# XML编程:从新手到实战高手的蜕变之路

一、引言&#xff1a;XML 在 C# 中的关键地位 在 C# 开发的广袤领域中&#xff0c;XML&#xff08;可扩展标记语言&#xff0c;eXtensible Markup Language&#xff09;宛如一颗璀璨的明星&#xff0c;占据着举足轻重的地位。它以其独特的结构化和自描述特性&#xff0c;成为了…...

kafka-leader -1问题解决

一. 问题&#xff1a; 在 Kafka 中&#xff0c;leader -1 通常表示分区的领导者副本尚未被选举出来&#xff0c;或者在获取领导者信息时出现了问题。以下是可能导致出现 kafka leader -1 的一些常见原因及相关分析&#xff1a; 1. 副本同步问题&#xff1a; 在 Kafka 集群中&…...

超大规模分类(四):Partial FC

人脸识别任务里&#xff0c;通常利用全连接层&#xff0c;来做人脸的分类。会面临三个实际问题&#xff1a; 真实的人脸识别数据噪声严重真实的人脸识别数据存在严重的长尾分布问题&#xff0c;一些类别样本多&#xff0c;多数类别样本少人脸类别越来越多&#xff0c;全连接层…...

uniapp 小程序如何实现大模型流式交互?前端SSE技术完整实现解析

文章目录 一、背景概述二、核心流程图解三、代码模块详解1. UTF-8解码器&#xff08;处理二进制流&#xff09;2. 请求控制器&#xff08;核心通信模块&#xff09;3. 流式请求处理器&#xff08;分块接收&#xff09;4. 数据解析器&#xff08;处理SSE格式&#xff09;5. 回调…...

因子分析详解:从理论到MATLAB实战

内容摘要&#xff1a; 本文系统解析因子分析的核心原理与MATLAB实战&#xff0c;涵盖数学模型、载荷矩阵估计、因子旋转及得分计算。通过上市公司盈利能力、消费者偏好等案例&#xff0c;演示数据标准化、因子提取与解释的全流程&#xff0c;并提供完整代码实现。深入对比因子分…...

【组态PLC】基于三菱西门子S7-200PLC和组态王液料混合系统组态设计【含PLC组态源码 M016期】

控制要求 总体控制要求&#xff1a;如面板图所示&#xff0c;本装置为三种液体混合模拟装置&#xff0c;由液面传感器SL1、SL2、SL3&#xff0c;液体A、B、C阀门与混合液阀门由电磁阀YV1、YV2、YV3、YV4&#xff0c;搅匀电机M&#xff0c;加热器H&#xff0c;温度传感器T组成。…...

js:根据后端返回的数组取出每一个数组的keyword字段然后拼接成一个逗号分隔的字符串

问&#xff1a; 现在有一个el-select&#xff0c; 后端接口返回数据为keyword:xxx,referenceNum:1,tagId:132sf32fasdfaf组成的数组&#xff0c; 现在select是多选&#xff0c; 但是但我选择多个下拉框选项后&#xff0c;后端需要前端返回的数据tagIds字段需要时一个字符串…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...