[QCustomPlot] 交互示例 Interaction Example

本文是官方例子的分析: Interaction Example
推荐笔记: qcustomplot使用教程–基本绘图
推荐笔记: 4.QCustomPlot使用-坐标轴常用属性

在这里插入图片描述

  • 官方例子需要用到很多槽函数, 这里先一次性列举, 自行加入到qt.h中.下面开始从简单的开始一个个分析.
    void qcustomplot_main_init(void);       // 初始化
    void titleDoubleClick(QMouseEvent* event); // 标题 双击
    void axisLabelDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part); // 标签 双击
    void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item); // 图例 双击
    void selectionChanged(void);            // 选择已更改
    void mousePress(void);                  // 鼠标按下
    void mouseWheel(void);                  // 鼠标滚轮
    void addRandomGraph(void);              // 添加随机图
    void removeSelectedGraph(void);         // 删除选定图形
    void removeAllGraphs(void);             // 删除所有图形
    void contextMenuRequest(QPoint pos);    // 上下文菜单请求
    void moveLegend(void);                  // 移动图例
    void graphClicked(QCPAbstractPlottable *plottable, int dataIndex); // 图表点击

1.图表点击

// 图表点击
void MainWindow::graphClicked(QCPAbstractPlottable *plottable, int dataIndex)
{
    //由于我们知道图中只有QCPG图,我们可以立即访问interface1D()
    //通常最好先检查interface1D()是否返回非零,然后再使用它。

    // plottable 表示绘图中对象的所有数据的抽象基类。更多。。。

    // 如果此plottable是一维plottable,即它实现了QCPPlottableInterface1D,则返回具有该类型的this指针。否则(例如在QCPColorMap的情况下)返回零。
    // interface1D() 您可以使用此方法获得对数据坐标的读取权限,同时只持有指向抽象基类的指针。

    // dataMainValue() 返回给定索引处数据点的主值。 主要值是什么,由plottable的数据类型定义。

    double dataValue = plottable->interface1D()->dataMainValue(dataIndex);
    QString message = QString("Clicked on graph '%1' at data point #%2 with value %3.").arg(plottable->name()).arg(dataIndex).arg(dataValue);
    // ui->statusBar->showMessage(message, 2500);
    qDebug() << message;
}
  • 当鼠标点击图标中的曲线时, 会回调该函数, 函数内可以获取曲线的名称和数据等. 并打印出最近的点坐标. 如果之后要显示文本游标,可以在这里显示;

2.移动图例

// 图像 移动图例
void MainWindow::moveLegend(void)
{
    QCustomPlot * customPlot = ui->customPlot;

    // 确保此插槽确实由上下文菜单操作调用,以便它携带我们需要的数据
    if (QAction* contextAction = qobject_cast<QAction*>(sender())) // 通过上下文菜单传入
    {
        bool ok;
        int dataInt = contextAction->data().toInt(&ok); // 获取传入的参数
        if (ok) // 数据解析正确, 这里应该添加确保位置枚举正确
        {
            customPlot->axisRect()->insetLayout()->setInsetAlignment(0, static_cast<Qt::Alignment>(dataInt)); // 设置图例的位置
            customPlot->replot(); // 重绘图像
        }
    }
}
  • 这个函数是用于移动图例时调用, 在右键菜单中点击选项后调用.

3.右键菜单/上下文菜单请求

// 图像 上下文菜单请求
void MainWindow::contextMenuRequest(QPoint pos)
{
    QCustomPlot * customPlot = ui->customPlot;

    QMenu *menu = new QMenu(this);              // 创建一个菜单
    menu->setAttribute(Qt::WA_DeleteOnClose);   // 当小部件接受关闭事件时,使Qt删除此小部件

    if (customPlot->legend->selectTest(pos, false) >= 0) // 请求图例的上下文菜单, 调用了上一个移动图例函数
    {
        menu->addAction("Move to top left", this, SLOT(moveLegend()))->setData(static_cast<int>(Qt::AlignTop|Qt::AlignLeft));           // 移动图例到左上角
        menu->addAction("Move to top center", this, SLOT(moveLegend()))->setData(static_cast<int>(Qt::AlignTop|Qt::AlignHCenter));      // 移动图例到中上角
        menu->addAction("Move to top right", this, SLOT(moveLegend()))->setData(static_cast<int>(Qt::AlignTop|Qt::AlignRight));         // 移动图例到右上角
        menu->addAction("Move to bottom right", this, SLOT(moveLegend()))->setData(static_cast<int>(Qt::AlignBottom|Qt::AlignRight));   // 移动图例到左下角
        menu->addAction("Move to bottom left", this, SLOT(moveLegend()))->setData(static_cast<int>(Qt::AlignBottom|Qt::AlignLeft));     // 移动图例到右下角
    }
    else  // 所需图形上的通用上下文菜单
    {
        menu->addAction("Add random graph", this, SLOT(addRandomGraph()));                  // 添加一条曲线
        if (customPlot->selectedGraphs().size() > 0)                                        // 如果选择的曲线数量大于0
            menu->addAction("Remove selected graph", this, SLOT(removeSelectedGraph()));    // 删除曲线
        if (customPlot->graphCount() > 0)                                                   // 如果全部曲线数量大于0
            menu->addAction("Remove all graphs", this, SLOT(removeAllGraphs()));            // 删除所有曲线
    }

    // 将小部件坐标pos转换为全局屏幕坐标。例如,mapToGlobal(QPoint(0,0))将给出小部件左上角像素的全局坐标。
    // 显示菜单,使动作atAction位于指定的全局位置p。要将小部件的局部坐标转换为全局坐标,
    menu->popup(customPlot->mapToGlobal(pos));
}
  • 在图像内右键时调用, 设定弹出的上下文菜单.
  • 先是判断点击位置是否在图例内, 如果是就弹出图例菜单, 否者就弹出曲线菜单;注意
  • 注意选择 菜单后调用的函数,传参的方法.

4.删除所有曲线

// 图像 删除所有图形
void MainWindow::removeAllGraphs()
{
    QCustomPlot * customPlot = ui->customPlot;

    customPlot->clearGraphs();  // 删除所有曲线, 坐标轴等内容是保留的
    customPlot->replot();       // 重绘图像
}
  • 注意是删除所有graphs,我发现其他例子中貌似有些曲线不算graphs;

5.删除选择曲线

// 图像 删除选定图形
void MainWindow::removeSelectedGraph()
{
    QCustomPlot * customPlot = ui->customPlot;

    if (customPlot->selectedGraphs().size() > 0) // 选择的曲线数量大于0
    {
        customPlot->removeGraph(customPlot->selectedGraphs().first()); // 删除特定的曲线, 选择曲线列表中的第一条
        customPlot->replot(); // 重绘图像
    }
}

6.添加随机曲线

// 图像 添加图像
void MainWindow::addRandomGraph()
{
    QCustomPlot * customPlot = ui->customPlot;

    int n = 50; // 图中的点数
    double xScale = (rand()/static_cast<double>(RAND_MAX) + 0.5)*2;
    double yScale = (rand()/static_cast<double>(RAND_MAX) + 0.5)*2;
    double xOffset = (rand()/static_cast<double>(RAND_MAX) - 0.5)*4;
    double yOffset = (rand()/static_cast<double>(RAND_MAX) - 0.5)*10;
    double r1 = (rand()/static_cast<double>(RAND_MAX) - 0.5)*2;
    double r2 = (rand()/static_cast<double>(RAND_MAX) - 0.5)*2;
    double r3 = (rand()/static_cast<double>(RAND_MAX) - 0.5)*2;
    double r4 = (rand()/static_cast<double>(RAND_MAX) - 0.5)*2;
    QVector<double> x(n), y(n);
    for (int i=0; i<n; i++)
    {
        x[i] = (i/static_cast<double>(n)-0.5)*10.0*xScale + xOffset;
        y[i] = (qSin(x[i]*r1*5)*qSin(qCos(x[i]*r2)*r4*3)+r3*qCos(qSin(x[i])*r4*2))*yScale + yOffset;
    }

    customPlot->addGraph(); // 添加曲线
    customPlot->graph()->setName(QString("New graph %1").arg(customPlot->graphCount()-1)); // 设置曲线图例名字
    customPlot->graph()->setData(x, y); // 设置数据
    customPlot->graph()->setLineStyle(static_cast<QCPGraph::LineStyle>(rand()%5+1)); // 设置曲线类型
    if (rand()%100 > 50)
        customPlot->graph()->setScatterStyle(QCPScatterStyle(static_cast<QCPScatterStyle::ScatterShape>(rand()%14+1))); // 设置点的类型
    QPen graphPen;
    graphPen.setColor(QColor(rand()%245+10, rand()%245+10, rand()%245+10)); // 设置颜色
    graphPen.setWidthF(rand()/static_cast<double>(RAND_MAX)*2+1); // 设置粗细
    customPlot->graph()->setPen(graphPen); // 设置线的颜色等
    customPlot->replot(); // 重绘
}
  • 这就是添加一些随机数据然后显示.设置了图线的显示样式;

7.鼠标滚轮缩放图像

// 图像 鼠标滚轮
void MainWindow::mouseWheel()
{
    QCustomPlot * customPlot = ui->customPlot;
    
    //如果选择了一个轴,则只允许缩放该轴的方向
    //如果未选择轴,则可以缩放两个方向

    if (customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis))               // 如果选择了坐标轴
        customPlot->axisRect()->setRangeZoom(customPlot->xAxis->orientation());     // 只缩放一个坐标轴
    else if (customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis))          // 如果选择了坐标轴
        customPlot->axisRect()->setRangeZoom(customPlot->yAxis->orientation());     // 只缩放一个坐标轴
    else
        customPlot->axisRect()->setRangeZoom(Qt::Horizontal|Qt::Vertical);          // 同时缩放两个坐标轴
}
  • 通过点击坐标来判断选择坐标轴的缩放,非常好的思路,就是不太习惯;

8.鼠标按下移动图像

// 图像 鼠标被按下
void MainWindow::mousePress()
{
    QCustomPlot * customPlot = ui->customPlot;

    //如果选择了轴,则只允许拖动该轴的方向
    //如果未选择轴,则可以拖动两个方向

    if (customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis))                 // 如果选择了坐标轴
        customPlot->axisRect()->setRangeDrag(customPlot->xAxis->orientation());       // 只移动一个坐标轴
    else if (customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis))            // 如果选择了坐标轴
        customPlot->axisRect()->setRangeDrag(customPlot->yAxis->orientation());       // 只移动一个坐标轴
    else
        customPlot->axisRect()->setRangeDrag(Qt::Horizontal|Qt::Vertical);            // 同时移动两个坐标轴
}

9.选择坐标轴或图例或曲线

// 图像 选择被修改
void MainWindow::selectionChanged(void)
{
    QCustomPlot * customPlot = ui->customPlot;

    /*
    通常,坐标轴基线、坐标轴刻度标签和坐标轴标签是可以单独选择的,但我们希望用户只能将整个坐标轴作为一个整体来选择,因此我们将刻度标签和坐标轴基线的选中状态绑定在一起。然而,坐标轴标签仍然可以单独选择。

    左侧和右侧坐标轴的选中状态应该同步,底部和顶部坐标轴的选中状态也应该同步。

    此外,我们希望将图形的选中状态与其对应的图例项的选中状态同步。这样,用户既可以通过点击图形本身来选择图形,也可以通过点击其图例项来选择图形。
    */

    //使上下轴同步选择,并将轴和刻度标签作为一个可选对象处理:
    if (customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis) || customPlot->xAxis->selectedParts().testFlag(QCPAxis::spTickLabels) ||
        customPlot->xAxis2->selectedParts().testFlag(QCPAxis::spAxis) || customPlot->xAxis2->selectedParts().testFlag(QCPAxis::spTickLabels))
    {
        customPlot->xAxis2->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels); // 如果其中一边坐标轴被选择, 那另一边的坐标轴也被同步选择
        customPlot->xAxis->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels);
    }

    //使左右轴同步选择,并将轴和刻度标签作为一个可选对象处理:
    if (customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis) || customPlot->yAxis->selectedParts().testFlag(QCPAxis::spTickLabels) ||
        customPlot->yAxis2->selectedParts().testFlag(QCPAxis::spAxis) || customPlot->yAxis2->selectedParts().testFlag(QCPAxis::spTickLabels))
    {
        customPlot->yAxis2->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels); // 如果其中一边坐标轴被选择, 那另一边的坐标轴也被同步选择
        customPlot->yAxis->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels);
    }

    //将图形的选择与相应图例项的选择同步:
    for (int i=0; i<customPlot->graphCount(); ++i)
    {
        QCPGraph *graph = customPlot->graph(i); // 获取图像对象
        QCPPlottableLegendItem *item = customPlot->legend->itemWithPlottable(graph); // 获取图例对象
        if (item->selected() || graph->selected()) // 如果图例或图像被选择, 就同步两个都被选择
        {
            item->setSelected(true);
            graph->setSelection(QCPDataSelection(graph->data()->dataRange()));
        }
    }
}
  • 用于同步选择对象, 选择了一边坐标轴就同时设置另一边也被选择.图例和曲线同理;
  • 注意函数的调用,暂时无法理解的话就照抄微改;

10.双击图例修改名字

// 图像 图例双击
void MainWindow::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item)
{
    QCustomPlot * customPlot = ui->customPlot;

    //双击图例项重命名图形
    Q_UNUSED(legend) // 消除报错
    if (item) //仅当项目被点击时才会做出反应(用户本可以在没有项目的地方点击图例的边框填充,则项目为0)
    {
        QCPPlottableLegendItem *plItem = qobject_cast<QCPPlottableLegendItem*>(item); // 对象类型转换
        bool ok;
        QString newName = QInputDialog::getText(this, "QCustomPlot example", "New graph name:", QLineEdit::Normal, plItem->plottable()->name(), &ok); // 使用弹窗获取文本
        if (ok) // 获取成功
        {
            plItem->plottable()->setName(newName); // 重新设置图例名字
            customPlot->replot(); // 重绘图像
        }
    }
}
  • 注意函数调用,其他不赘述了;

11.双击坐标轴修改名字

// 图像 标签双击
void MainWindow::axisLabelDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part)
{
    QCustomPlot * customPlot = ui->customPlot;

    // Set an axis label by double clicking on it
    if (part == QCPAxis::spAxisLabel) // only react when the actual axis label is clicked, not tick label or axis backbone
    {
        bool ok;
        QString newLabel = QInputDialog::getText(this, "QCustomPlot example", "New axis label:", QLineEdit::Normal, axis->label(), &ok);
        if (ok)
        {
            axis->setLabel(newLabel);
            customPlot->replot();
        }
    }
}
  • 注意函数调用,和上一个功能类似,其他不赘述了;

12.双击标题修改名字

// 图像 标题双击
void MainWindow::titleDoubleClick(QMouseEvent* event)
{
    QCustomPlot * customPlot = ui->customPlot;

    Q_UNUSED(event)
    if (QCPTextElement *title = qobject_cast<QCPTextElement*>(sender()))
    {
        // Set the plot title by double clicking on it
        bool ok;
        QString newTitle = QInputDialog::getText(this, "QCustomPlot example", "New plot title:", QLineEdit::Normal, title->text(), &ok);
        if (ok)
        {
            title->setText(newTitle);
            customPlot->replot();
        }
    }
}
  • 注意函数调用,和上一个功能类似,其他不赘述了;

13.初始化图表内容

// 图像 初始化
void MainWindow::qcustomplot_main_init(void)
{
    QCustomPlot * customPlot = ui->customPlot; // 方便调用

    customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables); // 允许拖动,缩放,选择坐标轴,选择图例,选择曲线;
    customPlot->xAxis->setRange(-8, 8);         // 设置初始范围
    customPlot->yAxis->setRange(-5, 5);         // 设置初始范围
    customPlot->axisRect()->setupFullAxesBox(); // 相当于开启右和上的坐标轴, 方便功能,在每侧创建一个还没有轴的轴,并将其可见性设置为true。此外,顶部/右侧轴被分配了底部/左侧轴的以下属性:

    customPlot->plotLayout()->insertRow(0);     // 插入一行?
    QCPTextElement *title = new QCPTextElement(customPlot, "Interaction Example", QFont("sans", 17, QFont::Bold));
    customPlot->plotLayout()->addElement(0, 0, title); // 在上面插入的那一行中? 添加标题

    customPlot->xAxis->setLabel("x Axis"); // 设置坐标轴名字
    customPlot->yAxis->setLabel("y Axis");
    customPlot->legend->setVisible(true); // 显示图例
    QFont legendFont = font();
    legendFont.setPointSize(10); // 设置字体大小
    customPlot->legend->setFont(legendFont);  // 设置字体
    customPlot->legend->setSelectedFont(legendFont); // 设置选择后的字体
    customPlot->legend->setSelectableParts(QCPLegend::spItems); // 图例框不可选择,只能选择图例项

    addRandomGraph(); // 添加随机曲线
    addRandomGraph();
    addRandomGraph();
    addRandomGraph();
    customPlot->rescaleAxes(); // 自适应坐标轴范围

    // 连接将某些轴选择连接在一起的插槽(特别是相对的轴):
    connect(customPlot, SIGNAL(selectionChangedByUser()), this, SLOT(selectionChanged())); // 选择时调用
    // 连接插槽时,请注意在选择轴时,只能拖动和缩放该方向:
    connect(customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress())); // 缩放时调用
    connect(customPlot, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheel())); // 拖动时调用

    // 使底部和左侧轴将其范围转移到顶部和右侧轴:
    connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis2, SLOT(setRange(QCPRange))); // 同步显示范围
    connect(customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->yAxis2, SLOT(setRange(QCPRange)));

    //连接一些交互插槽:
    connect(customPlot, SIGNAL(axisDoubleClick(QCPAxis*,QCPAxis::SelectablePart,QMouseEvent*)), this, SLOT(axisLabelDoubleClick(QCPAxis*,QCPAxis::SelectablePart))); // 双击时修改
    connect(customPlot, SIGNAL(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*,QMouseEvent*)), this, SLOT(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*)));
    connect(title, SIGNAL(doubleClicked(QMouseEvent*)), this, SLOT(titleDoubleClick(QMouseEvent*)));

    //当单击图形时,连接插槽会在状态栏中显示一条消息:
    connect(customPlot, SIGNAL(plottableClick(QCPAbstractPlottable*,int,QMouseEvent*)), this, SLOT(graphClicked(QCPAbstractPlottable*,int)));

    //为上下文菜单弹出设置策略和连接槽:
    customPlot->setContextMenuPolicy(Qt::CustomContextMenu); // 小部件如何显示上下文菜单
    connect(customPlot, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequest(QPoint)));
}
  • 初始化内容, 设置初始的允许操作,设置初始化的图例, 添加初始化的曲线,连接交互用的槽函数;
  • 注意拖动和缩放的交互是如何实现的.

14.总结

  • 至此已经能实现一些基本的交互和操作, 接下来就是显示游标和文字.

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

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

相关文章

WPF控件Grid的布局和C1FlexGrid的多选应用

使用 Grid.Column和Grid.Row布局&#xff0c;将多个C1FlexGrid布局其中&#xff0c;使用各种事件来达到所需效果&#xff0c;点击复选框可以加载数据到列表&#xff0c;移除列表的数据&#xff0c;自动取消复选框等 移除复选框的要注意&#xff01;&#xff01;&#xff01;&am…

04、Redis深入数据结构

一、简单动态字符串SDS 无论是Redis中的key还是value&#xff0c;其基础数据类型都是字符串。如&#xff0c;Hash型value的field与value的类型&#xff0c;List型&#xff0c;Set型&#xff0c;ZSet型value的元素的类型等都是字符串。redis没有使用传统C中的字符串而是自定义了…

生物医学信号处理--随机信号的数字特征

前言 概率密度函数完整地表现了随机变量和随机过程的统计性质。但是信号经处理后再求其概率密度函数往往较难&#xff0c;而且往往也并不需要完整地了解随机变量或过程的全部统计性质只要了解其某些特定方面即可。这时就可以引用几个数值来表示该变量或过程在这几方面的特征。…

LabVIEW数据库管理系统

LabVIEW数据库管理系统&#xff08;DBMS&#xff09;是一种集成了数据库技术与数据采集、控制系统的解决方案。通过LabVIEW的强大图形化编程环境&#xff0c;结合数据库的高效数据存储与管理能力&#xff0c;开发人员可以实现高效的数据交互、存储、查询、更新和报告生成。LabV…

合并模型带来的更好性能

研究背景与问题提出 在人工智能领域&#xff0c;当需要处理多个不同任务时&#xff0c;有多种方式来运用模型资源。其中&#xff0c;合并多个微调模型是一种成本效益相对较高的做法&#xff0c;相较于托管多个专门针对不同任务设计的模型&#xff0c;能节省一定成本。然而&…

Virgo:增强慢思考推理能力的多模态大语言模型

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

本地缓存:Guava Cache

这里写目录标题 一、范例二、应用场景三、加载1、CacheLoader2、Callable3、显式插入 四、过期策略1、基于容量的过期策略2、基于时间的过期策略3、基于引用的过期策略 五、显示清除六、移除监听器六、清理什么时候发生七、刷新八、支持更新锁定能力 一、范例 LoadingCache<…

Android adb shell GPU信息

Android adb shell GPU信息 先 adb shell 进入控制台。 然后&#xff1a; dumpsys | grep GLES Android adb shell命令捕获systemtrace_android 抓trace-CSDN博客文章浏览阅读2.5k次&#xff0c;点赞2次&#xff0c;收藏8次。本文介绍了如何使用adbshell命令配合perfetto工…

ElasticSearch | Elasticsearch与Kibana页面查询语句实践

关注&#xff1a;CodingTechWork 引言 在当今大数据应用中&#xff0c;Elasticsearch&#xff08;简称 ES&#xff09;以其高效的全文检索、分布式处理能力和灵活的查询语法&#xff0c;广泛应用于各类日志分析、用户行为分析以及实时数据查询等场景。通过 ES&#xff0c;用户…

RK3588平台开发系列讲解(系统篇)Linux Kconfig的语法

文章目录 一、什么是Kconfig二、config模块三、menuconfig四、menu 和 endmenu五、choice 和 endchoice六、source七、depends on八、default九、help十、逻辑表达式沉淀、分享、成长,让自己和他人都能有所收获!😄 一、什么是Kconfig Kconfig的语法及代码结构非常简单。本博…

STM32 USB组合设备 MSC CDC

STM32 USB组合设备 MSC CDC实现 教程 教程请看大佬niu_88 手把手教你使用USB的CDCMSC复合设备&#xff08;基于stm32f407&#xff09; 大佬的教程很好&#xff0c;很详细&#xff0c;我调出来了&#xff0c;代码请见我绑定的资源 注意事项 值得注意的是&#xff1a; 1、 cu…

深入学习RabbitMQ的Direct Exchange(直连交换机)

RabbitMQ作为一种高性能的消息中间件&#xff0c;在分布式系统中扮演着重要角色。它提供了多种消息传递模式&#xff0c;其中Direct Exchange&#xff08;直连交换机&#xff09;是最基础且常用的一种。本文将深入介绍Direct Exchange的原理、应用场景、配置方法以及实践案例&a…

Node.js——path(路径操作)模块

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

【Verdi实用技巧-Part2】

Verdi实用技巧-Part2 2 Verdi实用技巧-Part22.1 Dump波形常用的task2.1.1 Frequently Used Dump Tasks2.1.2 Demo 2.2 提取波形信息小工具--FSDB Utilities2.3 Debug in Source code view2.3.1 Find Scopes By Find Scope form 2.3.2 Go to line in Souce code View2.3.3 Use B…

web-前端小实验4

实现以上图片中的内容 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>用户注册</title&…

NLP项目实战——基于Bert模型的多情感评论分类(附数据集和源码)

在当今数字化的时代&#xff0c;分析用户评论中的情感倾向对于了解产品、服务的口碑等方面有着重要意义。而基于强大的预训练语言模型如 Bert 来进行评论情感分析&#xff0c;能够取得较好的效果。 在本次项目中&#xff0c;我们将展示如何利用 Python 语言结合transformers库&…

TAS测评倍智题库 | 益丰大药房2025年中高层测评BA商业推理测评真题考什么?

您好&#xff01;您已被邀请参加360评估。您的评估与反馈将有助于被评估人更深入地了解个人情况&#xff0c;发现个人优势和潜在风险。请您秉持公正、开放的心态进行评估。请尽快完成评估&#xff0c;在此衷心感谢您的配合与支持&#xff01; ​ 相关事宜&#xff1a; 请您在…

优秀的大模型会不会做坏事?

主要围绕大型语言模型&#xff08;LLMs&#xff09;在特定情境下可能出现的欺骗行为及相关研究展开&#xff0c;具体如下&#xff1a; 研究背景与核心发现&#xff1a;研究发现即使在用户无意激励的情况下&#xff0c;LLMs 也可能说谎&#xff0c;而能使用工具的模型更易被诱导…

fiscoBcos落盘加密介绍

落盘加密 落盘加密是在机构内部进行的&#xff0c;每个机构独立管理自己硬盘数据的安全。内网中&#xff0c;每个节点的硬盘数据是被加密的。所有加密数据的访问权限&#xff0c;通过Key Manager来管理。Key Manager是部署在机构内网内&#xff0c;专门管理节点硬盘数据访问秘…

完全二叉树的删除

&#xff08;1&#xff09;删除叶子节点 找到要删除的节点 targetNode找到要删除节点的父节点parent&#xff08;父节点是否存在&#xff09;要删除的节点是父节点的左子树还是右子树如果是左子树&#xff0c;则parent.leftnull;如果是右子树则parent.rightnull。 &#xff08;…