VS2019+CMake+Vtk9.3.0+Qt5.14.2 配置

VS2019+CMake+Vtk9.3.0+Qt5.14.2 配置环境

第一步 下载

基本配置

  • 系统环境:windows11 x64

  • Qt:5.14.2

    这是最后最新的LTS qt离线版本,后续版本都需要在线安装,同时使用qt5.14也避免版权问题。

    • Qt 5.14:大部分模块基于LGPL v3许可,允许以动态链接的方式使用而不公开源码,适合开发闭源、商业软件。
    • Qt 6:虽然也提供LGPL v3和GPL许可,但部分模块在GPL下提供,可能会有更严格的开源要求。此外,Qt 6的早期版本中缺少了一些模块,如图表、数据可视化和WebEngine,这可能会影响某些应用的开发
  • VTK:9.3.0

    VTK 9.3.0 发布于 2023 年 11 月 9 日

  • CMake:3.29

    CMake 3.29发布于 2024 年 3 月 26 日

  • VS2019

    因为qt5.14 默认使用msvc2017,也就是VS2019的编译器,虽说通过一些设置也可以在VS2022跑起来,不过图省事,还是使用VS2019了。

下载链接

请添加图片描述

链接:https://pan.baidu.com/s/1lbwPTIx-FKuVxX54AbzXGw?pwd=3cyi
提取码:3cyi

安装Qt

运行qt-opensource-windows-x86-5.14.2.exe , 注意安装路径下不要用中文,也不要有空格!

设置好路径,一路next,只有这里需要稍微注意下

在这里插入图片描述

安装CMake

安装VS2019

运行vs_community__2019.exe

安装c++桌面开发即可

第二步 编译VTK

过程相当痛苦,所以我才写这个攻略 orz

配置CMake

1.初步Configure

在这里插入图片描述

qt配置

检查qt的配置项,注意标红的几点,如果没有Qt附带的拿下Dir,设置好Qt5_Dir后再Configure一次,应该都会刷新出来。

另外如果你安装了anaconda,你的qt里面可能会是anaconda里的qt路径,需要更新正确。

在这里插入图片描述

安装位置

自定义一个安装位置,这是后续编译好的库文件和头文件的存放位置。

在这里插入图片描述

2.Generate

点击generate, 会在build文件夹下生成VTK.sln,使用VS2019打开该解决方案。

在这里插入图片描述

3.进入VS生成

编译时选择【生成->批生成】

先生成Debug和Release的库

在这里插入图片描述

编译时间视个人配置各不相同。几十分钟到几小时不等。

生成好后再进行批安装。

在这里插入图片描述

一切顺利的话,安装结果如下:

在这里插入图片描述
在这里插入图片描述

如果实在嫌麻烦也可以使用我已经编译好的库,下载链接里也有。

FAQ:

1. FilterReduction报错重编译的解决方法

https://blog.csdn.net/martian665/article/details/139340218

加上/force(注意空格)

在这里插入图片描述

不过/force 只是强制link,可能会导致别的问题。

2. 获取当前目录下lib的名称

将下面的代码写入文件,修改后缀名bat。运行即可得。

@echo off
dir /b *.lib > lib_files.txt
echo "All *.lib file names have been written to lib_files.txt"

第三部 配置

配置环境变量(否则运行时有问题)

环境变量->Path里加上如下bin的路径,具体需要根据你自己的安装位置做适配

  • D:\Program Files\CMake\bin
  • D:\Dev\VTK\bin
  • D:\Qt5\Qt5.14.2\5.14.2\msvc2017_64\bin
  • D:\Qt5\Qt5.14.2\5.14.2\msvc2017\bin

第四部 测试demo

demo1简单图形

在这里插入图片描述

CMakelists
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)project(Tutorial_Step1)find_package(VTK COMPONENTS CommonColorCommonCoreFiltersSourcesInteractionStyleRenderingContextOpenGL2RenderingCoreRenderingFreeTypeRenderingGL2PSOpenGL2RenderingOpenGL2
)if (NOT VTK_FOUND)message(FATAL_ERROR "Tutorial_Step1: Unable to find the VTK build folder.")
endif()# Prevent a "command line is too long" failure in Windows.
set(CMAKE_NINJA_FORCE_RESPONSE_FILE "ON" CACHE BOOL "Force Ninja to use response files.")
add_executable(Tutorial_Step1 MACOSX_BUNDLE Tutorial_Step1.cpp )target_link_libraries(Tutorial_Step1 PRIVATE ${VTK_LIBRARIES}
)
# vtk_module_autoinit is needed
vtk_module_autoinit(TARGETS Tutorial_Step1MODULES ${VTK_LIBRARIES}
)
Tutorial_Step1.cpp
#include"vtkSmartPointer.h"
#include"vtkPolyData.h"
#include "vtkType.h"
#include "vtkPoints.h"
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkPolyData.h"
#include "vtkPointData.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif
#define CIR_CUT (100.0)
namespace Data
{//存放点集using Point = std::vector<double>;using Pointlist = std::vector<Point>;//绘制面的索引using Triangular = std::vector<vtkIdType>;using TriangularList = std::vector<Triangular>;
}
int main()
{//设置内环,外环半径double Rinner = 20.0;double Rexcir = 40.0;Data::Pointlist mPointlist;Data::TriangularList mTriangularList;//std::vector<double> angles;angles.reserve(CIR_CUT + 1);double angleInterval = (2 * M_PI) / CIR_CUT;for (auto i = 0; i <= CIR_CUT; i++)angles.push_back(i * angleInterval);//生成点集和三角面for (auto index = 0; index < CIR_CUT; index++){__int64 lastsize = mPointlist.size();Data::Point p1 = { Rinner * cos(angles[index]), Rinner * sin(angles[index]), 0.0 };Data::Point p2 = { Rinner * cos(angles[index + 1]), Rinner * sin(angles[index + 1]), 0.0 };Data::Point p3 = { Rexcir * cos(angles[index + 1]), Rexcir * sin(angles[index + 1]), 0.0 };Data::Point p4 = { Rexcir * cos(angles[index]), Rexcir * sin(angles[index]), 0.0 };Data::Triangular f1 = { 0 + lastsize, 1 + lastsize, 2 + lastsize };Data::Triangular f2 = { 2 + lastsize, 3 + lastsize, 0 + lastsize };mPointlist.push_back(p1);mPointlist.push_back(p2);mPointlist.push_back(p3);mPointlist.push_back(p4);mTriangularList.push_back(f1);mTriangularList.push_back(f2);}//可视化流程//source源,绘制图形的基本数据vtkSmartPointer<vtkPoints> cirpoints = vtkSmartPointer<vtkPoints>::New();vtkSmartPointer<vtkCellArray> cellarray = vtkSmartPointer<vtkCellArray>::New();vtkSmartPointer<vtkFloatArray> calaes = vtkSmartPointer<vtkFloatArray>::New();for (__int64 index = 0; index < mPointlist.size(); index++){cirpoints->InsertPoint(index, mPointlist[index].data());calaes->InsertTuple1(index, index);}for (auto&& i : mTriangularList)cellarray->InsertNextCell(vtkIdType(i.size()), i.data());vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();polydata->SetPoints(cirpoints);polydata->SetPolys(cellarray);polydata->GetPointData()->SetScalars(calaes);//过滤器--这里没有使用,可以跳过//映射器通过将数据表现为有形的几何图形vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputData(polydata);mapper->SetScalarRange(polydata->GetScalarRange());//关闭根据标量设置颜色mapper->ScalarVisibilityOff();//表演者 调整可见的属性vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);actor->GetProperty()->SetColor(1.0, 0.5, 1.0);//渲染器vtkSmartPointer<vtkRenderer> render = vtkSmartPointer<vtkRenderer>::New();render->AddActor(actor);//渲染窗口vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(render);//渲染窗口交互器vtkSmartPointer<vtkRenderWindowInteractor> ri = vtkSmartPointer<vtkRenderWindowInteractor>::New();ri->SetRenderWindow(rw);actor->GetProperty()->SetRepresentationToWireframe();//显示边框rw->Render();ri->Start();return 0;
}

demo2 MinimalQtVTKApp

VTK+Qt

CMakelists
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)if(POLICY CMP0020)cmake_policy(SET CMP0020 NEW)cmake_policy(SET CMP0071 NEW)
endif()PROJECT(MinimalQtVTKApp)find_package(VTK COMPONENTS CommonCoreCommonDataModelFiltersSourcesGUISupportQtInteractionStyleRenderingContextOpenGL2RenderingCoreRenderingFreeTypeRenderingGL2PSOpenGL2RenderingOpenGL2GUISupportQtRenderingQt
)if(NOT VTK_FOUND)message(FATAL_ERROR "MinimalQtVTKApp: Unable to find the VTK build folder.")
endif()if(NOT(TARGET VTK::GUISupportQt))message(FATAL_ERROR "MinimalQtVTKApp: VTK not built with Qt support.")
endif()if(NOT DEFINED VTK_QT_VERSION)set(VTK_QT_VERSION 5)
endif()set(qt_components Core Gui Widgets)
if(${VTK_QT_VERSION} VERSION_GREATER_EQUAL 6)list(APPEND qt_components OpenGLWidgets)
endif()
list(SORT qt_components)
# We have ui files, so this will also bring in the macro:
#   qt5_wrap_ui or qt_wrap_ui from Widgets.
find_package(Qt${VTK_QT_VERSION} QUIETREQUIRED COMPONENTS ${qt_components}
)foreach(_qt_comp IN LISTS qt_components)list(APPEND qt_modules "Qt${VTK_QT_VERSION}::${_qt_comp}")
endforeach()message (STATUS "VTK_VERSION: ${VTK_VERSION}, Qt Version: ${Qt${VTK_QT_VERSION}Widgets_VERSION}")# Instruct CMake to run moc and uic automatically when needed.
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})file(GLOB UI_FILES *.ui)
file(GLOB QT_WRAP *.h)
file(GLOB CXX_FILES *.cxx)# For VTK versions greater than or equal to 8.90.0:
#  CMAKE_AUTOUIC is ON so we handle uic automatically for Qt targets.
#  CMAKE_AUTOMOC is ON so we handle moc automatically for Qt targets.# Prevent a "command line is too long" failure in Windows.
set(CMAKE_NINJA_FORCE_RESPONSE_FILE "ON" CACHE BOOL "Force Ninja to use response files.")
# CMAKE_AUTOMOC in ON so the MOC headers will be automatically wrapped.
add_executable(MinimalQtVTKApp MACOSX_BUNDLE${CXX_FILES} ${UISrcs} ${QT_WRAP}
)
if (Qt${VTK_QT_VERSION}Widgets_VERSION VERSION_LESS "5.11.0")qt5_use_modules(MinimalQtVTKApp ${qt_components})
else()target_link_libraries(MinimalQtVTKApp ${qt_modules})
endif()
target_link_libraries(MinimalQtVTKApp ${VTK_LIBRARIES})
# vtk_module_autoinit is needed
vtk_module_autoinit(TARGETS MinimalQtVTKAppMODULES ${VTK_LIBRARIES}
)
MinimalQtVTKApp.cpp
#include <QVTKOpenGLNativeWidget.h>
#include <vtkActor.h>
#include <vtkDataSetMapper.h>
#include <vtkDoubleArray.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkPointData.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>#include <QApplication>
#include <QDockWidget>
#include <QGridLayout>
#include <QLabel>
#include <QMainWindow>
#include <QPointer>
#include <QPushButton>
#include <QVBoxLayout>#include <cmath>
#include <cstdlib>
#include <random>namespace {
/*** Deform the sphere source using a random amplitude and modes and render it in* the window** @param sphere the original sphere source* @param mapper the mapper for the scene* @param window the window to render to* @param randEng the random number generator engine*/
void Randomize(vtkSphereSource* sphere, vtkMapper* mapper,vtkGenericOpenGLRenderWindow* window, std::mt19937& randEng);
} // namespaceint main(int argc, char* argv[])
{QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());QApplication app(argc, argv);// Main window.QMainWindow mainWindow;mainWindow.resize(1200, 900);// Control area.QDockWidget controlDock;mainWindow.addDockWidget(Qt::LeftDockWidgetArea, &controlDock);QLabel controlDockTitle("Control Dock");controlDockTitle.setMargin(20);controlDock.setTitleBarWidget(&controlDockTitle);QPointer<QVBoxLayout> dockLayout = new QVBoxLayout();QWidget layoutContainer;layoutContainer.setLayout(dockLayout);controlDock.setWidget(&layoutContainer);QPushButton randomizeButton;randomizeButton.setText("Randomize");dockLayout->addWidget(&randomizeButton);// Render area.QPointer<QVTKOpenGLNativeWidget> vtkRenderWidget =new QVTKOpenGLNativeWidget();mainWindow.setCentralWidget(vtkRenderWidget);// VTK part.vtkNew<vtkGenericOpenGLRenderWindow> window;vtkRenderWidget->setRenderWindow(window.Get());vtkNew<vtkSphereSource> sphere;sphere->SetRadius(1.0);sphere->SetThetaResolution(100);sphere->SetPhiResolution(100);vtkNew<vtkDataSetMapper> mapper;mapper->SetInputConnection(sphere->GetOutputPort());vtkNew<vtkActor> actor;actor->SetMapper(mapper);actor->GetProperty()->SetEdgeVisibility(true);actor->GetProperty()->SetRepresentationToSurface();vtkNew<vtkRenderer> renderer;renderer->AddActor(actor);window->AddRenderer(renderer);// Setup initial status.std::mt19937 randEng(0);::Randomize(sphere, mapper, window, randEng);// connect the buttonsQObject::connect(&randomizeButton, &QPushButton::released,[&]() { ::Randomize(sphere, mapper, window, randEng); });mainWindow.show();return app.exec();
}namespace {
void Randomize(vtkSphereSource* sphere, vtkMapper* mapper,vtkGenericOpenGLRenderWindow* window, std::mt19937& randEng)
{// Generate randomness.double randAmp = 0.2 + ((randEng() % 1000) / 1000.0) * 0.2;double randThetaFreq = 1.0 + (randEng() % 9);double randPhiFreq = 1.0 + (randEng() % 9);// Extract and prepare data.sphere->Update();vtkSmartPointer<vtkPolyData> newSphere;newSphere.TakeReference(sphere->GetOutput()->NewInstance());newSphere->DeepCopy(sphere->GetOutput());vtkNew<vtkDoubleArray> height;height->SetName("Height");height->SetNumberOfComponents(1);height->SetNumberOfTuples(newSphere->GetNumberOfPoints());newSphere->GetPointData()->AddArray(height);// Deform the sphere.for (int iP = 0; iP < newSphere->GetNumberOfPoints(); iP++){double pt[3] = {0.0};newSphere->GetPoint(iP, pt);double theta = std::atan2(pt[1], pt[0]);double phi =std::atan2(pt[2], std::sqrt(std::pow(pt[0], 2) + std::pow(pt[1], 2)));double thisAmp =randAmp * std::cos(randThetaFreq * theta) * std::sin(randPhiFreq * phi);height->SetValue(iP, thisAmp);pt[0] += thisAmp * std::cos(theta) * std::cos(phi);pt[1] += thisAmp * std::sin(theta) * std::cos(phi);pt[2] += thisAmp * std::sin(phi);newSphere->GetPoints()->SetPoint(iP, pt);}newSphere->GetPointData()->SetScalars(height);// Reconfigure the pipeline to take the new deformed sphere.mapper->SetInputDataObject(newSphere);mapper->SetScalarModeToUsePointData();mapper->ColorByArrayComponent("Height", 0);window->Render();
}
} // namespace
成功结果

点击 Randomize 可以切换渲染模型

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ROS服务通信机制实操C++

ROS服务通信实操C 步骤流程VScode 配置服务端客户端编辑配置文件编译并执行优化实现参数的动态提交优化先启动客户端后启动服务端 ROS服务通信的理论查阅&#xff1a;ROS服务通信流程理论 ROS服务通信的自定义srv数据的准备可以查阅&#xff1a;ROS服务通信自定义srv 在模型实…

使用Docker 实现 MySQL 循环复制(三)

系列文章 使用Docker 实现 MySQL 循环复制&#xff08;一&#xff09; 使用Docker 实现 MySQL 循环复制&#xff08;二&#xff09; 目录 系列文章1. 在主机上安装MySQL客户端2. 配置循环复制拓扑2.1 进入容器2.2 创建复制用户并授予复制权限2.3 复位二进制日志2.4 配置环形复…

Navicat安装

1.安装包下载。 2.双击exe文件&#xff0c;一直点下一步即可&#xff0c;可以修改安装位置 3.双击PatchNavicat.exe&#xff0c;在下方位置输入navicat的安装位置 4.提示成功

【Linux】线程——线程池、线程池的实现、线程安全的线程池、单例模式的概念、饿汉和懒汉模式、互斥锁、条件变量、信号量、自旋锁、读写锁

文章目录 Linux线程7. 线程池7.1 线程池介绍7.2 线程池的实现7.3 线程安全的线程池7.3.1 单例模式的概念7.3.2 饿汉和懒汉模式 8. 常见锁使用汇总8.1 互斥锁&#xff08;Mutex&#xff09;8.2 条件变量&#xff08;Condition Variable&#xff09;8.3 信号量&#xff08;Semaph…

Ubantu 使用 docker 配置 + 远程部署 + 远程开发

大家好我是苏麟 , Ubantu 一些配置 . 视频 : 服务器很贵&#xff1f;搞台虚拟机玩玩&#xff01;保姆级 Linux 远程开发教程_哔哩哔哩_bilibili Docker安装及配置 安装命令 : sudo apt install docker.io 查看版本号 : docker -v 查看虚拟机地址命令 : ifconfig 虚拟机地址 或…

maven项目打成可运行的jar及pom中的依赖一同打包

maven项目打jar及pom中的依赖一同打包 最近开发中有个需求&#xff0c;不部署新的服务&#xff0c;只jar包执行 那maven项目中&#xff0c;代码如何以jar的方式运行、如何把代码打成jar、pom中的依赖如何与代码一同打到jar包中&#xff1f; 1、代码如何以jar的方式运行&…

海豚调度器(DolphinScheduler)集群搭建详细笔记

海豚调度器集群搭建笔记 1.DolphinScheduler Cluster部署1.1 集群部署规划1.2 集群准备工作1.3 初始化数据库1.4 修改安装环境配置1.5 安装DolphinScheduler1.6 启停命令1.7 登录 DolphinScheduler UI 1.DolphinScheduler Cluster部署 分布式去中心化易扩展的工作流任务调度系…

CTF-Web习题:[HFCTF2021]Unsetme

题目链接&#xff1a;[HFCTF2021]Unsetme 解题思路 打开靶场发现是一段PHP源码 做一下代码审阅&#xff1a; <?php// Kickstart the framework $f3require(lib/base.php);//引入f3框架源码$f3->set(DEBUG,1);//f3对象设置DEBUG属性 if ((float)PCRE_VERSION<8.0)…

腾讯元宝上线“3D角色梦工厂”:快速生成专属3D角色!

7月16日&#xff0c;腾讯旗下大模型应用“腾讯元宝”上线“3D角色梦工厂”&#xff0c;允许用户通过上传一张五官清晰的正面头像&#xff0c;并选择不同的角色模板&#xff0c;迅速生成个人3D角色&#xff01; 技术特点 “3D角色梦工厂”将大模型生成技术与3D应用相结合&#…

JavaDS —— 二叉树

树的基本概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看 起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 树形结构中&#xff0c;子树之间不能有…

02线性表 - 链表

这里是只讲干货不讲废话的炽念&#xff0c;这个系列的文章是为了我自己以后复习数据结构而写&#xff0c;所以可能会用一种我自己能够听懂的方式来描述&#xff0c;不会像书本上那么枯燥和无聊&#xff0c;且全系列的代码均是可运行的代码&#xff0c;关键地方会给出注释^_^ 全…

十六、【机器学习】【监督学习】- 支持向量回归 (SVR)

系列文章目录 第一章 【机器学习】初识机器学习 第二章 【机器学习】【监督学习】- 逻辑回归算法 (Logistic Regression) 第三章 【机器学习】【监督学习】- 支持向量机 (SVM) 第四章【机器学习】【监督学习】- K-近邻算法 (K-NN) 第五章【机器学习】【监督学习】- 决策树…

GaussDB常见调优指南

文章目录 GaussDB常见调优指南一. Analyze 统计信息解析二. Explain 分布式计划解析三. 性能调优总体策略详解四. 性能调优之坏味道 SQL 识别五. 性能调优之好味道表定义六. 性能调优之 SQL 改写七. 性能调优之路径干预八. 性能调优之 Plan hint 运用九. 性能调优之 GUC 参数调…

C学习(数据结构)-->单链表习题

目录 一、环形链表 题一&#xff1a;环形链表 思路&#xff1a; 思考一&#xff1a;为什么&#xff1f; 思考二&#xff1a;快指针一次走3步、4步、......n步&#xff0c;能否相遇 step1&#xff1a; step2&#xff1a; 代码&#xff1a; 题二&#xff1a; 环形链表 I…

SAE J1939协议入门(一)

一、SAE J1939是什么 SAE J1939&#xff08;以下简称J1939&#xff09;是由汽车工程师协会&#xff08;SAE &#xff09;定义的标准&#xff0c;专门用于提供微处理器系统之间的串行数据通信。虽然CAN存在并且被广泛用于小型车辆&#xff0c;但J1939被设计为大型车辆复杂网络的…

深度挖掘行情接口:股票市场中的关键金融数据API接口解析

在股票市场里&#xff0c;存在若干常见的股票行情数据接口&#xff0c;每一种接口皆具备独特的功能与用途。以下为一些常见的金融数据 API 接口&#xff0c;其涵盖了广泛的金融数据内容&#xff0c;其中就包含股票行情数据&#xff1a; 实时行情接口 实时行情接口&#xff1a…

恒创科技:如何解决“服务器 IP 地址无法被找到”的错误

如何解决“服务器 IP 地址无法被找到”的错误?此错误通常出现在你的设备无法使用其分配的 IP 地址与网络服务器通信时。问题的来源可能多种多样&#xff0c;从简单的拼写错误到复杂的 DNS 和路由问题。以下是对“服务器 IP 地址无法找到”的常见原因以及可以采取的解决办法。 …

万界星空科技MES系统生产计划管理的功能

MES系统&#xff08;Manufacturing Execution System&#xff0c;制造执行系统&#xff09;的生产计划管理功能是其核心功能之一&#xff0c;旨在将企业的生产计划转化为实际的生产操作&#xff0c;并通过实时监控和调整来确保生产活动的顺利进行。以下是MES系统生产计划管理功…

SpringData JPA Mongodb 查询部分字段

JPA 网上用的好像不多&#xff0c;找了好多材料以后最终找了这个可行的方案&#xff1a; Query(fields "{tender_id:1,_id:0}")List<MGPltTender> findByTenderIdIsNotNull(PageRequest pageRequest); 调用&#xff1a; Sort sort Sort.by(popularType.getC…

【二维区域和检索-矩阵不可变】python刷题记录

一夜无解&#xff0c;痛苦&#xff0c;遂拜倒于灵神门下&#xff0c;妄做狂徒也&#xff01; . - 力扣&#xff08;LeetCode&#xff09; 灵神秒解如下&#xff1a; class NumMatrix:#二维初始矩阵def __init__(self, matrix: List[List[int]]):mlen(matrix)nlen(matrix[0])#…