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 框架中,存在三种不同的坐标系,分别是 物品坐标系(Item Coordinates)、场景坐标系(Scene Coordinates) 和 视图坐标系(View Coordinates)。这三种坐标系在图形…...
轻松搭建:使用Anaconda创建虚拟环境并在PyCharm中配置
一、使用Anaconda创建虚拟环境 1. 安装Anaconda 2..conda常用的命令 3. 创建虚拟环境-以搭建MachineVision为例 4. 激活虚拟环境 5. 安装依赖包 二、PyCharm配置环境 在进行Python项目开发时,合理的环境管理是必不可少的,特别是当你在多个项目中…...
Unity TMPro显示中文字体
TMP默认的字体只能显示英语,那么怎么显示中文呢 1、找到支持中文的字体文件 在c盘搜索Fonts文件夹有很多支持中文的字体文件 我这里选择雅黑 PS.双击打开发现里面有粗体细体普通三个版本,也可以只导入一个版本进去 2、将其拖入到unity Assets里面 3…...
【嵌入式原理设计】实验五:远程控制翻盖设计
目录 一、实验目的 二、实验环境 三、实验内容 四、实验记录及处理 五、实验小结 六、成果文件提取链接 一、实验目的 熟悉和掌握舵机及串口控制方式 二、实验环境 Win10ESP32实验开发板 三、实验内容 1、熟悉舵机的控制方式; 2、用串口发…...
矩阵乘积态简介
定义 矩阵乘积态(Matrix Product State, MPS)是一种用于表示量子多体系统的强大工具,特别是在一维系统中。MPS 是一种张量网络状态,它通过将全局量子态分解为一系列局部张量的乘积来有效地表示量子态。 注释: 量子态表…...
国自然面上项目|基于肺癌精准靶向治疗的基因影像组学研究|基金申请·25-02-26
小罗碎碎念 今天和大家分享一个国自然面上项目,执行年限为2019.01~2022.12,直接费用为57万元。 项目旨在解决肺癌靶向治疗耐药问题,通过整合多组学和影像组学技术构建预测模型。 研究期间,对非小细胞肺癌 CT 影像组学…...
OA办公系统自动渗透测试过程
目录 一、下载环境源码 二、部署环境 三、测试 XSS漏洞 SQL注入 文件上传漏洞 一、下载环境源码 OA源码打包地址: https://download.csdn.net/download/weixin_43650289/90434502?spm=1001.2014.3001.5503 二、部署环境...
Fisher信息矩阵(Fisher Information Matrix,简称FIM)
Fisher信息矩阵简介 Fisher信息矩阵(Fisher Information Matrix,简称FIM)是统计学和信息理论中的一个重要概念,广泛应用于参数估计、统计推断和机器学习领域。它以统计学家罗纳德费希尔(Ronald Fisher)的名…...
nginx反向代理以及负载均衡(常见案例)
一、nginx反向代理 1、什么是代理服务器? 代理服务器,客户机在发送请求时,不会直接发送给目的主机,而是先发送给代理服务器,代理服务接受客户机请求之后,再向主机发出,并接收目的主机返回的数据…...
LabVIEW形状误差测量系统
在机械制造领域,形状与位置公差(GD&T)直接影响装配精度与产品寿命。国内中小型机加工企业因形状误差导致的返工率高达12%-18%。传统测量方式存在以下三大痛点: 设备局限:机械式千分表需人工读数,精度…...
将VsCode变得顺手好用(1
目录 设置中文 配置调试功能 提效和增强相关插件 主题和图标相关插件 创建js文件 设置中文 打开【拓展】 输入【Chinese】 下载完成后重启Vs即可变为中文 配置调试功能 在随便一个位置新建一个文件夹,用于放置调试文件以及你未来写的代码,随便命名但…...
排序模板——C++
0.排序模板题目 题目描述 将读入的 N 个数从小到大排序后输出。 输入格式 第一行为一个正整数 N。 第二行包含 N 个空格隔开的正整数 ai,为你需要进行排序的数。 输出格式 将给定的 N 个数从小到大输出,数之间空格隔开,行末换行且无空格。 …...
HTTP/HTTPS 服务端口监测的简易实现
一 HTTP/HTTPS 服务端口监测的简易实现方法 在当今快节奏的工作环境中,工作忙碌成为了许多职场人的常态。就拿我们团队最近经历的事情来说,工作任务一个接一个,大家都在各自的岗位上争分夺秒地忙碌着。然而,就在这样高强度的工作…...
快速入门——状态管理VueX
Vuex介绍 状态管理 每一个Vuex应用的核心都是一个store,与普通的全局对象不同的是,基于Vue数据与视图绑定的特点,当store中的状态发生变化时,与之绑定的视图也会被重新渲染。 store中的状态不允许被直接修改,改变sto…...
C# 根据Ollama+DeepSeekR1开发本地AI辅助办公助手
在上一篇《访问DeepSeekR1本地部署API服务搭建自己的AI办公助手》中,我们通过通过Ollama提供的本地API接口用Python实现了一个简易的AI办公助手,但是需要运行Py脚本,还比较麻烦,下面我们用C#依据Ollama提供的API接口开发一个本地A…...
Flutter - 基础Widget
Flutter 中万物皆 Widget,基础Widget 同步对应 Android View. 普通文本 Text /*** 控制文本样式统一使用 style:TextStyle, 例:fontSize(字体大小),color(颜色),shadows(阴影)等等* 控制文本布局需单独设置:* textAlign(文不对齐方式)* te…...
Tips :仿真竞争条件 指的是什么?
文章目录 **为什么会出现仿真竞争条件?****典型场景举例****System Verilog 如何解决竞争条件?****1. 使用 `program` 块隔离测试平台****2. 使用 `clocking` 块明确时序关系****3. 非阻塞赋值(`<=`)的合理使用****竞争条件的根本原因****总结****代码结构****1. 设计模…...
【Elasticsearch】script_fields 和 runtime_fields的区别
script_fields和runtime_fields都是 Elasticsearch 中用于动态计算字段值的功能,但它们在实现方式、应用场景和性能表现上存在显著区别。以下是两者的详细对比: 1.定义和应用场景 • script_fields: • 定义:通过 Painless 脚本…...
达梦DTS数据迁移工具生产篇(MySQL->DM8)
本文章使用的DTS工具为 2024年9月18日的版本,使用的目的端DM8数据库版本为2023年12月的版本,注意数据库版本和DTS版本之间跨度不要太大,以免出现各种兼容性的报错。若发现版本差距过大时,请联系达梦技术服务工程师处理。 1. 迁移…...
【安卓逆向】逆向APP界面UI修改再安装
1.背景 有一客户找到我,说能不能把APP首页的底部多余界面去掉。 逆向实战 想要去除安卓应用软件中的内容,需要对APP逆向进行修改再打包。 通过工具 MIT管理器工具 提取APK包,点击apk文件,点击查看反编译apk。 搜索关键字。这里关键…...
企业级大模型应用的Java-Python异构融合架构实践
一、后端语言相关技术生态 Python语言 Python在AI计算领域拥有全面的生态支持: 底层工具库: Pandas、NumPy、SciPy、Matplotlib深度学习框架: PyTorch、TensorFlow领域专用框架: HuggingFace Transformers(社区生态为主) 常见Python框架 …...
深度剖析数据中台架构图,铸造数字文明的基石
🔥🔥 AllData大数据产品是可定义数据中台,以数据平台为底座,以数据中台为桥梁,以机器学习平台为中层框架,以大模型应用为上游产品,提供全链路数字化解决方案。 ✨奥零数据科技官网:http://www.aolingdata.com ✨AllData开源项目:https://github.com/alldatacenter/a…...
python实现基于文心一言大模型的sql小工具
一、准备工作 注册与登录: 登录百度智能云千帆控制台,注册并登录您的账号。 创建千帆应用: 根据实际需求创建千帆应用。创建成功后,获取AppID、API Key、Secret Key等信息。如果已有千帆应用,可以直接查看已有应用的AP…...
飞腾腾锐D2000 + OpenHarmony 4.1release部署deepseek大模型
简介 1.1 飞腾腾锐D2000 飞腾腾锐D2000是一款面向桌面应用的高性能通用处理,集成8个飞腾自主研发的高能效处理器核FTC663,兼 容64位ARMv8指令集并支持ARM64和ARM32两种执行模式,支持单精度、双精度浮点运算指令和ASIMD处理 指令,主…...
进程概念、PCB及进程查看
文章目录 一.进程的概念进程控制块(PCB) 二.进程查看通过指令查看进程通过proc目录查看进程的cwd和exe获取进程pid和ppid通过fork()创建子进程 一.进程的概念 进程是一个运行起来的程序,而程序是存放在磁盘的,cpu要想执行程序的指…...
Oracle 数据库基础入门(一):搭建数据管理基石
在当今数字化时代,数据库作为数据管理的核心工具,对于各类应用系统的开发至关重要。尤其是在 Java 全栈开发领域,掌握一款强大的数据库技术是必备技能。Oracle 数据库以其卓越的性能、高度的可靠性和丰富的功能,在企业级应用中广泛…...
selenium如何实现,开启浏览器的开发者工具模式,并且开启 toggle移动设备模拟模式
核心实现代码 pythonCopy Code from selenium import webdriver from selenium.webdriver.chrome.options import Options def enable_devtools_with_toggle(): options Options() # 强制开启开发者工具 options.add_argument("--auto-open-devtools-for-tabs&quo…...
分布式锁实现(数据库+Redis+Zookeeper)
1. 数据库分布式锁 实现原理 基于唯一索引: 创建一张锁表,通过唯一索引(如锁名称)保证互斥性。 加锁:插入一条记录,成功则获取锁,失败则重试。 解锁:删除对应记录。 乐观锁&…...
七、Spring Boot:初识与项目搭建
深入解析 Spring Boot:初识与项目搭建 Spring Boot 是基于 Spring Framework 的开源 Java 基础框架,旨在简化 Spring 应用的开发过程。它通过“约定优于配置”的理念,极大地减少了开发中的配置工作,同时提供了“开箱即用”的功能…...
记录一下用docker克隆某授权制定ip的环境恢复
#首先还是要看日志根据问题去进行调整 java web的老项目配置文件一般是 bin启动里边的脚本 还有conf中的 xml配置文件 再或者就是classes中的配置文件,再或者就是lib中的jar包中的配置文件 1.安装docker 2.创建docker网络 docker network create --driver bridge --subnet…...
【含文档+PPT+源码】基于微信小程序的健康饮食食谱推荐平台的设计与实现
项目介绍 本课程演示的是一款基于微信小程序的健康饮食食谱推荐平台的设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本…...
主流虚拟化技术讲解
目录 VMware vSphere Microsoft Hyper-V KVM(Kernel-based Virtual Machine) OpenStack VMware vSphere 架构与组件:VMware vSphere 是基于裸金属虚拟化技术的平台,核心组件包括 ESXi 主机和 vCenter Server。ESXi 是虚拟化层…...
java开发——为什么要使用动态代理?
举个例子:假如有一个杀手专杀男的,不杀女的。代码如下: public interface Killer {void kill(String name, String sex);void watch(String name); }public class ManKiller implements Killer {Overridepublic void kill(String name, Stri…...
kotlin 知识点一 变量和函数
在Kotlin中定义变量的方式和Java 区别很大,在Java 中如果想要定义一个变 量,需要在变量前面声明这个变量的类型,比如说int a表示a是一个整型变量,String b表 示b是一个字符串变量。而Kotlin中定义一个变量,只允许在变量…...
将CUBE或3DL LUT转换为PNG图像
概述 在大部分情况下,LUT 文件通常为 CUBE 或 3DL 格式。但是我们在 OpenGL Shader 中使用的LUT,通常是图像格式的 LUT 文件。下面,我将教大家如何将这些文件转换为 PNG 图像格式。 条形LUT在线转换(不是8x8网络)&am…...
侯捷 C++ 课程学习笔记:类的声明与构造函数
目录 一、类的声明 二、内联函数 三、访问级别 四、构造函数 五、构造函数重载 六、实际应用案例 七、学习心得 一、类的声明 类的声明是定义类的基本结构,包括类的成员变量和成员函数。类的声明分为类头和类体两部分。 类头(class head…...
BGP状态和机制
BGP邻居优化 为了增加稳定性,通常建议实验回环口来建立邻居。更新源:建立邻居和邻居所学习到的路由的下一跳。多跳:EBGP邻居建立默认选哟直连,因为TTL=1,如果非直连,必须修改TTL。命令备注peer 2.2.2.2 connect-interface lo1配置更新源peer 2.2.2.2 ebgp-max-hop 2配置T…...
MongoDB 数据库简介
MongoDB 数据库简介 引言 随着互联网技术的飞速发展,数据已经成为企业的重要资产。为了高效地管理和处理这些数据,数据库技术应运而生。MongoDB作为一种流行的NoSQL数据库,因其灵活的数据模型和高效的数据处理能力,受到了广泛的关注。本文将为您详细介绍MongoDB的基本概念…...
浏览器下载vue.js.devtools,谷歌浏览器和edg浏览器
1、谷歌浏览器下载: 情况一:如果谷歌应用商店可以打开,那么就直接到谷歌应用商店下载,直接搜索vue.js.devtools添加扩展即可。 情况二:谷歌浏览器的谷歌应用商城打不开,那么就百度搜索极简插件找到vue.js.…...
Android AOSP系统裁记录
Android 系统裁剪是指根据需求移除不必要的组件和功能,以优化系统性能、减少存储占用或满足特定设备需求。以下是 Android 系统裁剪的基本步骤: 1. 准备环境 操作系统:推荐使用 Ubuntu 或 macOS。 工具: Android SDK Android N…...
Could not download npm for node v14.21.3(nvm无法下载节点v14.21.3的npm)
场景描述:之前的项目用的是node以前的版本,使用nvm没下载下来,npm命令执行不了 错误如下图,15版本的node同理,下载的都是.exe可执行文件的扩展名,使用npm命令终端无法识别 解决思路:去node官网…...
React进阶之React核心源码解析(三)
React核心源码解析 diff多节点比较diff两轮遍历比较第一轮比较第二轮比较Update 状态更新Concurrent Modediff 多节点比较diff isArray方法比较 节点更新// 更新前 <ul><li key="0" className="before">0<li><li key=...
2025吐槽季第一弹---腾讯云EO边缘安全加速平台服务
前言: 关于EO边缘安全加速平台服务 参照:产品概述,具体如下: 边缘安全加速平台 EO(Tencent Cloud EdgeOne,下文简称为 EdgeOne)是国内首款基于全新架构的真正一体化的边缘安全加速平台。提供全面的安全防…...
Dify自定义工作流集成指南:对接阿里云百炼文生图API的实现方案
dify工作流的应用基本解释 dify应用发布相关地址:应用发布 | Dify 根据官方教程,我们可以看到dify自定义的工作流可以发布为----工具 这个教程将介绍如何通过工作流建立一个使用阿里云百炼文生图模型。 工具则可以给其他功能使用,如agent…...
WebSocket简单介绍 并接入deepseek
目录 什么是 WebSocket?工作原理: 为什么需要 WebSocket?WebSocket 的优势HTTP 和 WebSocket 的区别WebSocket 的劣势WebSocket 的应用场景WebSocket 握手过程1. 客户端发起握手请求2. 服务器响应握手请求3. 建立连接 WebSocket 事件处理WebS…...
android 新增native binder service 方式(三)
书接上回,继续第三种方式,是手动生成 service binder 的方法,项目结构 1,编译aidl aidl 文件保持不变,如何生成Bn和Bp 文件呢。 aidl -I ./libserviceaidl/aidl -h ./ -o ./ --langcpp libserviceaidl/aidl/com/test/IService.a…...
linux--多进程开发(5)--进程
进程间通讯概念 每两个进程之间都是独立的资源分配单元,不同进程之间不能直接访问另一个进程的资源。 但不同的进程需要进行信息的交互和状态的传递等,因此需要进程间通信(IPC,inter processes cimmunication) 进程通信的目的: …...
分享httprunner 结合django实现平台接口自动化方案
说明,可以直接在某个视图集定义自定义接口来验证。 调试1:前端界面直接编写yaml文件. 新增要实现存数据到mysql,同时存文件到testcase下, 如test.yaml 更新yaml数据,同时做到更新 testcase下的文件,如test.yaml acti…...
前端面试题之HTML篇
1.src和href的区别 src用于替换当前元素,href用于在当前文档和引用资源之间确立联系。 src可用于img、input、style、script、iframe---同步加载执行 href可用于link、a---异步 1.用途不同 src 用于引入外部资源,通常是图像、视频、JavaScript 文件等&am…...
Selenium 调用模型接口实现功能测试
要使用 Selenium 调用模型接口实现功能测试,可按以下步骤进行: 1. 环境准备 安装 Selenium:使用 pip install selenium 安装 Selenium 库。安装浏览器驱动:根据使用的浏览器(如 Chrome、Firefox 等)下载对应的驱动,并将其添加到系统的环境变量中。例如,Chrome 浏览器需…...