【qt】CAD下

目录

  • 一.前言
  • 二.缩放
    • 1.逻辑
    • 2.获取图形项选中的个数
    • 3.获取图形项并放大
    • 4.视图缩放
    • 5.完整代码
    • 6.效果展示
    • 7.缩小完整代码
  • 三.旋转
    • 1.图形项进行旋转
    • 2.视图的旋转
    • 3.完整代码
    • 4.效果展示
    • 5.右转代码
  • 四.恢复
    • 1.图形项复原
    • 2.视图复原
    • 3.完整代码
    • 4.效果展示
  • 五.前后置
    • 1.设置z轴的值
    • 2.后置代码
  • 六.组合和拆分
    • 1.逻辑
    • 2.创建图形项组
    • 3.图形项添加到组
    • 4.设置组的标识
    • 5.完整代码
    • 6.效果演示
    • 7.拆分代码
    • 8.效果展示
  • 七.删除
    • 1.删除代码
  • 八.双击编辑图形项颜色
    • 1.逻辑
    • 2.获取图形项的类型
    • 3.画刷模版函数
    • 4.图形项类型的判断
    • 5.画笔模版函数
    • 6.线条图形项
    • 7.文本图形项
    • 8.效果展示
  • 九.按键微移
    • 1.逻辑
    • 2.删除图形项
    • 3.旋转图形项
    • 4.放大,放小
    • 5.上下左右
    • 6.完整代码
  • 十.鼠标移动
    • 1.逻辑
    • 2.状态栏添加标签
    • 3.设置视图,场景坐标
    • 4.效果展示
  • 十一.鼠标单击
    • 1.逻辑
    • 2.通过场景坐标获取图形项
    • 3.场景坐标转换成图形项坐标
    • 4.设置图形项的信息
    • 5.完整代码
    • 6.效果展示![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1acd1a3fe0fb42248b72bd9c4d9e48dd.png)
  • 十二.总结

一.前言

我的发,好久没有更新了,忙着考试去了,只剩下最后一科英语了,我赶紧来更新,哈哈,上节课我们的CAD项目还没有做完呢,OK,那就来咯!
我们上节课的成果:
在这里插入图片描述
上节课我们只实现了左边工具栏的功能,但是我们上面的工具栏的功能还没有进行实现,所以我们现在话不多说,直接开干!

二.缩放

1.逻辑

我们可以选择一个或者多个图形项
为了演示功能,我们如果选择的一个就对图形项进行缩放
如果选择的多个就对视图进行缩放

2.获取图形项选中的个数

void MainWindow::on_actionBig_triggered()
{
    int count=scene->selectedItems().count();
}

看不懂?不存在的,看我的
在这里插入图片描述
**selectedItems()返回的一个装图形项指针的列表,所以我们可以用count()**来统计个数,哈哈.

3.获取图形项并放大

if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setScale(item->scale()+0.1);
    }

如果选中的个数为1,那么是对图形项进行操作!
刚刚说了**selectedItems()返回的是一个列表,所以可以用at()**来获取到图形项.
**setScale()**见名知意,这个就是用来缩放图形项的,此处是在原有的基础上进行缩放.
在这里插入图片描述

4.视图缩放

其他的情况我们就用视图的缩放

else
    {
        ui->graphicsView->scale(1.1,1.1);
    }

可以直接设置,不用像图形项一样获取原来的,因为看下图的翻译
在这里插入图片描述

5.完整代码

void MainWindow::on_actionBig_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setScale(item->scale()+0.1);
    }
    else
    {
        ui->graphicsView->scale(1.1,1.1);
    }
}

6.效果展示

在这里插入图片描述
这个是放大了的,可惜暂时还不会给你录动态图进行展示,哈哈.

7.缩小完整代码

解:由上同理可得,哈哈,想起了我的初中数学.

void MainWindow::on_actionSmall_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setScale(item->scale()-0.1);
    }
    else
    {
        ui->graphicsView->scale(0.9,0.9);
    }
}

运行结果就你们自己去试了!

三.旋转

1.图形项进行旋转

讲过的地方我就不讲了.

int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setRotation(item->rotation()-30);
    }

还是在原有的基础上进行旋转.
在这里插入图片描述

2.视图的旋转

 else
    {
        ui->graphicsView->rotate(-30);
    }

负号是逆时针进行旋转哦.
在这里插入图片描述

3.完整代码

void MainWindow::on_actionLeft_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setRotation(item->rotation()-30);
    }
    else
    {
        ui->graphicsView->rotate(-30);
    }
}

4.效果展示

在这里插入图片描述

5.右转代码

void MainWindow::on_actionRight_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setRotation(item->rotation()+30);
    }
    else
    {
        ui->graphicsView->rotate(+30);
    }
}

四.恢复

1.图形项复原

int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setRotation(0);
        item->setScale(1.0);
    }

只需要将缩放倍数设置为1,旋转设置为0即可

2.视图复原

else
    {
        ui->graphicsView->resetTransform();
    }

在这里插入图片描述

3.完整代码

void MainWindow::on_actionHuifu_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setRotation(0);
        item->setScale(1.0);
    }
    else
    {
        ui->graphicsView->resetTransform();
    }
}

4.效果展示

在这里插入图片描述
自己去玩完.

五.前后置

1.设置z轴的值

void MainWindow::on_actionTop_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setZValue(item->zValue()+1);
    }
}

在原来的基础上对,z的值进行加1层!
在这里插入图片描述

2.后置代码

void MainWindow::on_actionButton_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto item=scene->selectedItems().at(0);
        item->setZValue(item->zValue()-1);
    }
}

自己去运行效果,我这里运行了,截图你们也看不出来!

六.组合和拆分

1.逻辑

我们将选中的多个图形项,放在一个图形项组中,相当于一个新的图像项.

2.创建图形项组

QGraphicsItemGroup* group=new QGraphicsItemGroup;
scene->addItem(group);

因为组可以视为当个项,所有我们可以添加到场景.
在这里插入图片描述

3.图形项添加到组

 for(int i=0;i<count;i++)
        {
            auto item=scene->selectedItems().at(0);
            item->setSelected(false);
            item->clearFocus();
            group->addToGroup(item);
        }

当我们添加到组以后,原来的图像项的选中和聚焦状态都取消.
在这里插入图片描述

4.设置组的标识

group->setFlags(QGraphicsItem::ItemIsMovable|
                QGraphicsItem::ItemIsSelectable|
                QGraphicsItem::ItemIsFocusable);
        group->setZValue(ZVaule++);
        scene->clearSelection();
        group->setSelected(true);

设置成可选中,可移动,可聚焦,同时设置z轴的值.
并将其设置为新的选中.

5.完整代码

void MainWindow::on_actionZuhe_triggered()
{
    int count=scene->selectedItems().count();
    if(count>1)
    {
        QGraphicsItemGroup* group=new QGraphicsItemGroup;
        scene->addItem(group);
        for(int i=0;i<count;i++)
        {
            auto item=scene->selectedItems().at(0);
            item->setSelected(false);
            item->clearFocus();
            group->addToGroup(item);
        }
        
        group->setFlags(QGraphicsItem::ItemIsMovable|
                        QGraphicsItem::ItemIsSelectable|
                        QGraphicsItem::ItemIsFocusable);
        group->setZValue(ZVaule++);
        scene->clearSelection();
        group->setSelected(true);
    }
    
}

6.效果演示

在这里插入图片描述
嘿嘿嘿,自己就可以组合成任何的图像,哈哈哈.

7.拆分代码

获取的图形项,强转类型转换为图形项组然后进行拆分.

void MainWindow::on_actionChaifen_triggered()
{
    int count=scene->selectedItems().count();
    if(count==1)
    {
        auto group=(QGraphicsItemGroup*)scene->selectedItems().at(0);
        scene->destroyItemGroup(group);
    }
}

在这里插入图片描述

8.效果展示

在这里插入图片描述

七.删除

1.删除代码

void MainWindow::on_actionDel_triggered()
{
    int count=scene->selectedItems().count();
    if(count>0)
    {
        for(int i=0;i<count;i++)
        {
            auto item=scene->selectedItems().at(0);
            scene->removeItem(item);
        }
    }
}

在这里插入图片描述

八.双击编辑图形项颜色

1.逻辑

因为每个图形项的设置颜色方式,不一定相同
有的设置画刷,有的设置画笔,所以我们要对图形项的类型进行判断
因为有很多不同的图形项,所以我们可以用一个模板函数来传参来进行处理.

2.获取图形项的类型

void MainWindow::on_graphicsView_mouseDoubleClick(QPoint point)
{
    int count =scene->selectedItems().count();
    if(count==0)
    {
        return;
    }

    auto item=scene->selectedItems().at(0);
    switch (item->type()) {
    }

type()返回的一个整数,可以用switch来进行判断!
在这里插入图片描述

3.画刷模版函数

template <class T>
void setBrushColor(T *item)
{
    QColor color=item->brush().color();
    color=QColorDialog::getColor(color,NULL,"选择填充颜色");
    if(color.isValid())
    {
        item->setBrush(QBrush(color));
    }
}

4.图形项类型的判断

switch (item->type()) {
    case QGraphicsRectItem::Type:
    {
        auto item2=qgraphicsitem_cast<QGraphicsRectItem*>(item);
        setBrushColor(item2);
        break;
    }
    case QGraphicsEllipseItem::Type:
    {
        auto item2=qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
        setBrushColor(item2);
        break;
    }
    case QGraphicsPolygonItem::Type:
    {
        auto item2=qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
        setBrushColor(item2);
        break;
    }
    }

这个几个都是一种类型的,调用模版函数设置画刷的颜色就可以!

5.画笔模版函数

template <class T>
void setPenColor(T*item)
{
    QPen pen;
    QColor color=item->pen().color();
    color=QColorDialog::getColor(color,NULL,"选择填充颜色");
    if(color.isValid())
    {
        pen.setColor(color);
        item->setPen(pen);
    }
}

6.线条图形项

因为不是用画刷进行填充颜色的,所以我们用画笔.

case QGraphicsLineItem::Type:
    {
        auto item2=qgraphicsitem_cast<QGraphicsLineItem*>(item);
        setPenColor(item2);
        break;
    }

7.文本图形项

case QGraphicsTextItem::Type:
    {
        auto item2=qgraphicsitem_cast<QGraphicsTextItem*>(item);
        QFont font;
        font=item2->font();
        bool ok=false;
        font=QFontDialog::getFont(&ok,font,this,"选择字体");
        if(ok)
        {
            item2->setFont(font);
        }
        break;
    }

用了一个字体对话框.

8.效果展示

在这里插入图片描述
在这里插入图片描述
非常的银杏.

九.按键微移

1.逻辑

我们上节课不写写了一个键盘事件嘛
现在我们可以根据键盘来对图形项进行操作

2.删除图形项

if(scene->selectedItems().count()!=1)
    {
        return;
    }
    
    auto item=scene->selectedItems().at(0);
    
    if(event->key()==Qt::Key_Delete)
    {
        scene->removeItem(item);
    }

就是键盘上的Delete键

3.旋转图形项

else if(event->key()==Qt::Key_Space)
    {
        item->setRotation(item->rotation()+10);
    }

Key_Space就是空格键.

4.放大,放小

else if(event->key()==Qt::Key_PageUp)
    {
        item->setScale(item->scale()+0.1);
    }
    else if(event->key()==Qt::Key_PageDown)
    {
        item->setScale(item->scale()-0.1);
    }

5.上下左右

else if(event->key()==Qt::Key_Left)
    {
        item->setX(item->x()-1);
    }
    else if(event->key()==Qt::Key_Right)
    {
        item->setX(item->x()+1);
    }
    else if(event->key()==Qt::Key_Up)
    {
        item->setY(item->y()-1);
    }
    else if(event->key()==Qt::Key_Down)
    {
        item->setY(item->y()+1);
    }

6.完整代码

void MainWindow::on_graphicsView_keyPress(QKeyEvent *event)
{
    if(scene->selectedItems().count()!=1)
    {
        return;
    }

    auto item=scene->selectedItems().at(0);

    if(event->key()==Qt::Key_Delete)
    {
        scene->removeItem(item);
    }
    else if(event->key()==Qt::Key_Space)
    {
        item->setRotation(item->rotation()+10);
    }
    else if(event->key()==Qt::Key_PageUp)
    {
        item->setScale(item->scale()+0.1);
    }
    else if(event->key()==Qt::Key_PageDown)
    {
        item->setScale(item->scale()-0.1);
    }
    else if(event->key()==Qt::Key_Left)
    {
        item->setX(item->x()-1);
    }
    else if(event->key()==Qt::Key_Right)
    {
        item->setX(item->x()+1);
    }
    else if(event->key()==Qt::Key_Up)
    {
        item->setY(item->y()-1);
    }
    else if(event->key()==Qt::Key_Down)
    {
        item->setY(item->y()+1);
    }
}

效果自己去用键盘玩哦!

十.鼠标移动

1.逻辑

当我们的鼠标进行移动的时候,我们就显示视图坐标和场景的坐标.
可通过视图坐标转到场景坐标.
同时,我们希望在状态栏中进行显示,所以我们需要在状态栏中,添加标签.

2.状态栏添加标签

我们原来讲过,状态栏添加组件,只能通过代码.
头文件中进行创建:
在这里插入图片描述
构造函数中,进行实现:

    labView=new QLabel("视图坐标:");
    labScene=new QLabel("场景坐标:");
    labItem=new QLabel("图形项坐标:");
    labInfo=new QLabel("图形项信息:");
    labView->setMinimumWidth(150);
    labScene->setMinimumWidth(150);
    labItem->setMinimumWidth(150);
    labInfo->setMinimumWidth(150);
    this->statusBar()->addWidget(labView);
    this->statusBar()->addWidget(labScene);
    this->statusBar()->addWidget(labItem);
    this->statusBar()->addWidget(labInfo);

运行结果:
在这里插入图片描述

3.设置视图,场景坐标

void MainWindow::on_graphicsView_mouseMove(QPoint point)
{
    labView->setText(QString::asprintf("视图坐标:%d,%d",point.x(),point.y()));
    QPointF pointScene=ui->graphicsView->mapToScene(point);
    labScene->setText(QString::asprintf("场景坐标:%.0f,%.0f",pointScene.x(),pointScene.y()));
}

返回的浮点坐标.
在这里插入图片描述

4.效果展示

在这里插入图片描述
会随着我的鼠标移动而变化!

十一.鼠标单击

1.逻辑

当我们单击一个图形项的时候,就显示图形项坐标和图形项的信息.

2.通过场景坐标获取图形项

QPointF pointScene=ui->graphicsView->mapToScene(point);
auto item=scene->itemAt(pointScene,ui->graphicsView->transform());

通过场景坐标得到场景中的项
在这里插入图片描述

3.场景坐标转换成图形项坐标

QPointF pointItem=item->mapFromScene(pointScene);//场景坐标转图形项坐标
labItem->setText(QString::asprintf("图形项坐标:%.0f,%.0f",pointItem.x(),pointItem.y()));

在这里插入图片描述

4.设置图形项的信息

还记得我们原理自己定义的数据嘛,就是setDate()
现在我们就可以拿出来用了.

labInfo->setText(item->data(ITEMINFO).toString()+"ITEMID:"+
                         item->data(ITEMID).toString());

在这里插入图片描述
在这里插入图片描述
这就是当年我们自定义数据的地方
在这里插入图片描述
现在就可以根据键来获取到,当时我们设置的图像名称和ID.

5.完整代码

void MainWindow::on_graphicsView_mousePress(QPoint point)
{
    QPointF pointScene=ui->graphicsView->mapToScene(point);
    auto item=scene->itemAt(pointScene,ui->graphicsView->transform());
    
    if(item)
    {
        QPointF pointItem=item->mapFromScene(pointScene);//场景坐标转图形项坐标
        labItem->setText(QString::asprintf("图形项坐标:%.0f,%.0f",pointItem.x(),pointItem.y()));
        labInfo->setText(item->data(ITEMINFO).toString()+" ID:"+
                         item->data(ITEMID).toString());
    }
}

6.效果展示在这里插入图片描述

OK,到这里,咱们这个项目就完结撒花啦,期待与你一起进步!

十二.总结

这就是基于QGraphicsView架构做的CAD项目,当然啦,还可以有更多的创意,你也试试看吧!

播下一颗种子…

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

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

相关文章

Day34:LeedCode 56. 合并区间 738.单调递增的数字 968.监控二叉树

56. 合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;int…

网约车停运损失费:1、事故经过

目录 &#x1f345;点击这里查看所有博文 随着自己工作的进行&#xff0c;接触到的技术栈也越来越多。给我一个很直观的感受就是&#xff0c;某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了&#xff0c;只有经常会用到的东西才有可能真正记…

时序分析基本概念介绍——min pulse width 最小脉冲宽度

文章目录 前言一、什么是 min pulse width&#xff1f;二、为什么检查 min pulse width&#xff1f;三、如何设置 min pulse width约束&#xff1f;1. 在sdc里面定义2. library里面定义 四、如何检查 min pulse width&#xff1f;五、如何修复 min pulse width&#xff1f;总结…

win7 的 vmware tools 安装失败

没有安装vmware tools的系统屏幕显示异常。桌面是比较小的图像&#xff0c;四周是黑边在 vmware 软件里 方法1&#xff0c;下补丁 https://www.catalog.update.microsoft.com/Search.aspx?qkb4474419 方法2&#xff0c;使用老版vm tools http://softwareupdate.vmware.com/c…

【STM32】USART串口通讯

1.USART简介 STM32芯片具有多个USART外设用于串口通讯&#xff0c;它是 Universal Synchronous Asynchronous Receiver and Transmitter的缩写&#xff0c; 即通用同步异步收发器可以灵活地与外部设备进行全双工数据交换。有别于USART&#xff0c; 它还有具有UART外设(Univers…

基于STM32+ESP8266打造智能家居温湿度监控系统(附源码接线图)

摘要: 本文将介绍如何使用STM32单片机、ESP8266 Wi-Fi模块和Python Flask框架构建一个完整的物联网系统&#xff0c;实现传感器数据采集、无线传输、云端存储及Web可视化展示。 关键词: STM32, ESP8266, 传感器, Flask, 物联网, 云平台, 数据可视化 1. 系统概述 本系统以STM…

Redis数据库(四):Redis数据库事务

经过前面的学习&#xff0c;我们就对于Redis数据库可以进行基本的操作&#xff0c;从这一节开始&#xff0c;我们就正式学习Redis数据库的相关知识&#xff0c;为以后工作打下坚实的基础。 目录 一、事务&#xff08;了解&#xff09; 1.1 Redis的事务概念 1.2 Redis事务…

海外品牌营销:TikTok达人合作中的挑战与对策

随着TikTok成为许多品牌进行营销推广的重要渠道&#xff0c;TikTok上达人也因其庞大的粉丝基础和强大的内容创作能力&#xff0c;成为品牌合作的首选对象。然而&#xff0c;在与TikTok达人合作的过程中&#xff0c;品牌也面临着诸多挑战&#xff0c;如合作沟通、内容创意、数据…

基于昇腾AI | Yolov7模型迁移到昇腾平台EA500I边缘计算盒子的实操指南

近年来&#xff0c;国产化替代的进程正在加快。在众多国产平台中&#xff0c;昇腾平台具有高性能、低功耗、易扩展、软件栈全面成熟等优势&#xff0c;其产品和技术在国内众多领域实现了广泛应用&#xff1b;作为昇腾的APN伙伴和IHV合作伙伴&#xff0c;英码科技携手昇腾推出了…

论文《Federated Recommendation with Additive Personalization》阅读

论文《Federated Recommendation with Additive Personalization》阅读 论文概况PreliminariesMethodologyExperiments消融实验ConvergenceCurriculum分析可视化 一点总结 今天带来的是 ICLR 2024 关于联邦推荐的论文《Federated Recommendation with Additive Personalization…

【摄像头标定】双目摄像头标定及矫正-opencv(python)

双目摄像头标定及矫正 棋盘格标定板标定矫正 棋盘格标定板 本文使用棋盘格标定板&#xff0c;可以到这篇博客中下载&#xff1a;https://blog.csdn.net/qq_39330520/article/details/107864568 标定 要进行标定首先需要双目拍的棋盘格图片&#xff0c;20张左右&#xff0c;…

易天智能eHR管理平台 CreateUser 任意用户添加漏洞复现

0x01 产品简介 易天智能eHR管理平台是一款功能全面、智能化的人力资源管理软件,旨在帮助企业提高人力资源管理效率和管理水平。该平台通过集成员工信息、薪酬管理、档案人事管理、绩效管理和招聘管理等多个模块,实现了人力资源管理的全面智能化管理。 0x02 漏洞概述 易天智…

Windows11环境下安装Vmware Workstation 16的方法

1、下载VMWare 从网盘下载 https://pan.baidu.com/share/init?surlUpcnqiRv6nUuzO0EOZ22zg 提取码&#xff1a;8888 2、安装VMware虚拟机   第1步&#xff1a;双击上面准备好的Vmware Workstation 16虚拟机软件安装包&#xff0c;即可看到如图所示的安装向导初始界面&#x…

为什么嵌入式驱动开发工程师可以拿高薪?

嵌入式驱动开发是技术密集型的工作。想象一下&#xff0c;每一个硬件设备都需要与之匹配的驱动程序&#xff0c;才能在操作系统中正常工作。刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论…

【知识学习】阐述Unity3D中MaterialTexture的概念及使用方法示例

在Unity3D中&#xff0c;Material和Texture是渲染过程中非常重要的两个概念&#xff0c;它们共同工作以实现丰富的视觉效果。 Material Material是Unity中的一个组件&#xff0c;用于定义物体表面的视觉属性。一个Material可以包含多种属性&#xff0c;如颜色、纹理、反射率等…

道路救援入驻派单小程序开源版开发

道路救援入驻派单小程序开源版开发 1、用户立即救援 2、后台收到救援通知&#xff0c;派单救援师傅. 道路救援入驻派单小程序通常会包含一系列功能&#xff0c;旨在方便救援服务提供商、用户和后台管理系统之间的交互。以下是一个可能的功能列表&#xff1a; 用户端功能&…

第1章 物联网模式简介---独特要求和体系结构原则

物联网用例的独特要求 物联网用例往往在功耗、带宽、分析等方面具有非常独特的要求。此外&#xff0c;物联网实施的固有复杂性&#xff08;一端的现场设备在计算上受到挑战&#xff0c;另一端的云容量几乎无限&#xff09;迫使架构师做出艰难的架构决策和实施选择。可用实现技…

秋招Java后端开发冲刺——非关系型数据库篇(MongoDB)

MongoDB 本文介绍非关系型数据库MongoDB的基础知识和常见面试题。 &#xff08;一&#xff09;基础知识 1. 介绍&#xff1a;MongoDB是一个基于分布式文件存储的数据库&#xff0c;由C语言编写&#xff0c;旨在为WEB应用提供可扩展的高性能数据存储解决方案。 2.特点 特点…

Rust日常开发三方库精选

日常开发三方库精选 对计算机、编程、架构的理解决定一个程序员的上限&#xff0c;而工具则决定了他的下限&#xff0c;三尺森寒利剑在手&#xff0c;问世间谁敢一战。 本文就分门别类的精心挑选了一些非常适合日常开发使用的三方库&#xff0c;同时针对优缺点、社区活跃等进…

聚类距离度量(保姆级讲解,包学会~)

在机器学习的聚类中&#xff0c;我们通常需要使用距离来进行类的划分&#xff0c;或者比较不同类之间的各种距离&#xff0c;这里我们介绍西瓜书上所提出的一些距离计算方式。 首先介绍一下距离的一些性质&#xff1a; 西瓜书上给出了四条性质&#xff0c;第一个是非负性&#…