UE5 c++将自定义UserWdiget添加到对应菜单栏

前言:

为了实现与UserWidget一致的右键添加,便有了此章
注:这里使用的是UE5.3

目标内容:

在这里插入图片描述

这里可以参考UserWidget的源码,拷贝一份属于自己的就ok(本篇章只是全改成了属于自己的CommonUserWidget)

Runtime模块需要添加内容

首先创建一份自己Runtime模块的对象,我这取名是UCommonUserWidget

.h

#pragma once#include "Blueprint/UserWidget.h"
#include "CommonUserWidget.generated.h"UCLASS(BlueprintType, Blueprintable)
class DIVINEPROLOGUE_API UCommonUserWidget : public UUserWidget
{GENERATED_BODY()
public:}
};

主要实现内容是:UFactory
这里需要创建一个Editor模块,添加以下代码:

.h

//这个创建是因为本着改了都改,就创建了一份
#pragma once
#include "WidgetBlueprint.h"
#include "CommonWidgetBlueprint.generated.h"/*** The widget blueprint enables extending UCommonWidgetBlueprint the user extensible UWidget.*/
UCLASS(BlueprintType)
class UCommonWidgetBlueprint : public UWidgetBlueprint
{GENERATED_BODY()
public:UCommonWidgetBlueprint(){}
};

.h

// Copyright Epic Games, Inc. All Rights Reserved.#pragma once#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "Templates/SubclassOf.h"
#include "Factories/Factory.h"
#include "Engine/Blueprint.h"
#include "CommonUserWidgetFactory.generated.h"UCLASS(HideCategories=Object, MinimalAPI)
class UCommonUserWidgetFactory : public UFactory
{GENERATED_UCLASS_BODY()// The type of blueprint that will be createdUPROPERTY(EditAnywhere, Category=WidgetBlueprintFactory)TEnumAsByte<enum EBlueprintType> BlueprintType;// The parent class of the created blueprintUPROPERTY(EditAnywhere, Category=WidgetBlueprintFactory, meta=(AllowAbstract = ""))TSubclassOf<class UUserWidget> ParentClass;//~ Begin UFactory Interfacevirtual bool ConfigureProperties() override;virtual bool ShouldShowInNewMenu() const override;virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn, FName CallingContext) override;virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override;//~ Begin UFactory Interface	private:UPROPERTY(Transient)TObjectPtr<UClass> RootWidgetClass;
};

.cpp

// Copyright Epic Games, Inc. All Rights Reserved.#include "CommonUserWidgetFactory.h"
#include "UObject/Interface.h"
#include "Misc/MessageDialog.h"
#include "Blueprint/UserWidget.h"
#include "Blueprint/WidgetBlueprintGeneratedClass.h"
#include "WidgetBlueprint.h"
#include "Kismet2/KismetEditorUtilities.h"
#include "Modules/ModuleManager.h"
#include "UMGEditorModule.h"#include "Blueprint/WidgetTree.h"
#include "UMGEditorProjectSettings.h"
#include "ClassViewerModule.h"
#include "Kismet2/SClassPickerDialog.h"
#include "ClassViewerFilter.h"
#include "CommonUserWidget.h"
#include "CommonWidgetBlueprint.h"
#include "Components/CanvasPanel.h"#define LOCTEXT_NAMESPACE "UCommonUserWidgetFactory"/*------------------------------------------------------------------------------UCommonUserWidgetFactory implementation.
------------------------------------------------------------------------------*/class FWidgetClassFilter : public IClassViewerFilter
{
public:/** All children of these classes will be included unless filtered out by another setting. */TSet <const UClass*> AllowedChildrenOfClasses;/** Disallowed class flags. */EClassFlags DisallowedClassFlags;virtual bool IsClassAllowed(const FClassViewerInitializationOptions& InInitOptions, const UClass* InClass, TSharedRef< FClassViewerFilterFuncs > InFilterFuncs) override{return !InClass->HasAnyClassFlags(DisallowedClassFlags)&& InFilterFuncs->IfInChildOfClassesSet(AllowedChildrenOfClasses, InClass) != EFilterReturn::Failed;}virtual bool IsUnloadedClassAllowed(const FClassViewerInitializationOptions& InInitOptions, const TSharedRef< const IUnloadedBlueprintData > InUnloadedClassData, TSharedRef< FClassViewerFilterFuncs > InFilterFuncs) override{return !InUnloadedClassData->HasAnyClassFlags(DisallowedClassFlags)&& InFilterFuncs->IfInChildOfClassesSet(AllowedChildrenOfClasses, InUnloadedClassData) != EFilterReturn::Failed;}};UCommonUserWidgetFactory::UCommonUserWidgetFactory(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer)
{bCreateNew = true;bEditAfterNew = true;SupportedClass = UCommonWidgetBlueprint::StaticClass();ParentClass = nullptr;
}bool UCommonUserWidgetFactory::ConfigureProperties()
{if (GetDefault<UUMGEditorProjectSettings>()->bUseUserWidgetParentClassViewerSelector || GetDefault<UUMGEditorProjectSettings>()->bUseUserWidgetParentDefaultClassViewerSelector){FClassViewerModule& ClassViewerModule = FModuleManager::LoadModuleChecked<FClassViewerModule>("ClassViewer");// Fill in optionsFClassViewerInitializationOptions Options;Options.DisplayMode = EClassViewerDisplayMode::Type::TreeView;Options.Mode = EClassViewerMode::ClassPicker;Options.bShowNoneOption = false;Options.bExpandAllNodes = true;Options.bShowDefaultClasses = GetDefault<UUMGEditorProjectSettings>()->bUseUserWidgetParentDefaultClassViewerSelector;Options.bShowClassesViewer = GetDefault<UUMGEditorProjectSettings>()->bUseUserWidgetParentClassViewerSelector;TSharedPtr<FWidgetClassFilter> Filter = MakeShareable(new FWidgetClassFilter);Options.ClassFilters.Add(Filter.ToSharedRef());const TArray<TSoftClassPtr<UUserWidget>>& FavoriteWidgetParentClasses = GetDefault<UUMGEditorProjectSettings>()->FavoriteWidgetParentClasses;for (int32 Index = 0; Index < FavoriteWidgetParentClasses.Num(); ++Index){UClass* FavoriteWidgetParentClass = FavoriteWidgetParentClasses[Index].LoadSynchronous();if (FavoriteWidgetParentClass && FavoriteWidgetParentClass->IsChildOf(UCommonUserWidget::StaticClass())){if (!Options.ExtraPickerCommonClasses.Contains(FavoriteWidgetParentClass)){Options.ExtraPickerCommonClasses.Add(FavoriteWidgetParentClass);}}}if (Options.ExtraPickerCommonClasses.Num() == 0){Options.ExtraPickerCommonClasses.Add(UCommonUserWidget::StaticClass());}Filter->DisallowedClassFlags = CLASS_Deprecated | CLASS_NewerVersionExists | CLASS_Hidden | CLASS_HideDropDown;Filter->AllowedChildrenOfClasses.Add(UCommonUserWidget::StaticClass());const FText TitleText = LOCTEXT("CreateCommonWidgetBlueprint", "Pick Parent Class for New  Widget Blueprint");UClass* ChosenParentClass = nullptr;bool isSuccessful = SClassPickerDialog::PickClass(TitleText, Options, ChosenParentClass, UCommonUserWidget::StaticClass());ParentClass = ChosenParentClass ? ChosenParentClass : UCommonUserWidget::StaticClass();if (!isSuccessful){return false;}}if (GetDefault<UUMGEditorProjectSettings>()->bUseWidgetTemplateSelector){// Load the classviewer module to display a class pickerFClassViewerModule& ClassViewerModule = FModuleManager::LoadModuleChecked<FClassViewerModule>("ClassViewer");// Fill in optionsFClassViewerInitializationOptions Options;Options.Mode = EClassViewerMode::ClassPicker;Options.bShowNoneOption = true;TArray<TSoftClassPtr<UPanelWidget>> CommonRootWidgetClasses = GetDefault <UUMGEditorProjectSettings>()->CommonRootWidgetClasses;for (int32 Index = 0; Index < CommonRootWidgetClasses.Num(); ++Index){UClass* PanelWidgetClass = CommonRootWidgetClasses[Index].LoadSynchronous();if (PanelWidgetClass && PanelWidgetClass->IsChildOf(UPanelWidget::StaticClass())){if (!Options.ExtraPickerCommonClasses.Contains(PanelWidgetClass)){Options.ExtraPickerCommonClasses.Add(PanelWidgetClass);}}}if (Options.ExtraPickerCommonClasses.Num() == 0){Options.ExtraPickerCommonClasses.Add(UCanvasPanel::StaticClass());}TSharedPtr<FWidgetClassFilter> Filter = MakeShareable(new FWidgetClassFilter);Options.ClassFilters.Add(Filter.ToSharedRef());Filter->DisallowedClassFlags = CLASS_Abstract | CLASS_Deprecated | CLASS_NewerVersionExists;Filter->AllowedChildrenOfClasses.Add(UPanelWidget::StaticClass());const FText TitleText = LOCTEXT("CreateRootWidgetBlueprint", "Pick Root Widget for New Widget Blueprint");return SClassPickerDialog::PickClass(TitleText, Options, static_cast<UClass*&>(RootWidgetClass), UPanelWidget::StaticClass());}return true;
}bool UCommonUserWidgetFactory::ShouldShowInNewMenu() const
{return true;
}UObject* UCommonUserWidgetFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn, FName CallingContext)
{// Make sure we are trying to factory a Anim Blueprint, then create and init onecheck(Class->IsChildOf(UCommonWidgetBlueprint::StaticClass()));UClass* CurrentParentClass = ParentClass;if (CurrentParentClass == nullptr){CurrentParentClass = UCommonUserWidget::StaticClass();}// If they selected an interface, force the parent class to be UInterfaceif (BlueprintType == BPTYPE_Interface){CurrentParentClass = UInterface::StaticClass();}if ( (CurrentParentClass == nullptr) || !FKismetEditorUtilities::CanCreateBlueprintOfClass(CurrentParentClass) || !CurrentParentClass->IsChildOf(UCommonUserWidget::StaticClass()) ){FFormatNamedArguments Args;Args.Add( TEXT("ClassName"), CurrentParentClass ? FText::FromString( CurrentParentClass->GetName()) : LOCTEXT("Null", "(null)") );FMessageDialog::Open( EAppMsgType::Ok, FText::Format( LOCTEXT("CannotCreateCommonWidgetBlueprint", "Cannot create a Common Widget Blueprint based on the class '{ClassName}'."), Args ) );return nullptr;}else{if (!GetDefault<UUMGEditorProjectSettings>()->bUseWidgetTemplateSelector){RootWidgetClass = GetDefault<UUMGEditorProjectSettings>()->DefaultRootWidget;}UCommonWidgetBlueprint* NewBP = CastChecked<UCommonWidgetBlueprint>(FKismetEditorUtilities::CreateBlueprint(CurrentParentClass, InParent, Name, BlueprintType, UCommonWidgetBlueprint::StaticClass(), UWidgetBlueprintGeneratedClass::StaticClass(), CallingContext));// Create the desired root widget specified by the projectif ( NewBP->WidgetTree->RootWidget == nullptr ){if (TSubclassOf<UPanelWidget> RootWidgetPanel = RootWidgetClass){UWidget* Root = NewBP->WidgetTree->ConstructWidget<UWidget>(RootWidgetPanel);NewBP->WidgetTree->RootWidget = Root;}}{IUMGEditorModule::FWidgetBlueprintCreatedArgs Args;Args.ParentClass = CurrentParentClass;Args.Blueprint = NewBP;IUMGEditorModule& UMGEditor = FModuleManager::LoadModuleChecked<IUMGEditorModule>("UMGEditor");UMGEditor.OnWidgetBlueprintCreated().Broadcast(Args);}return NewBP;}
}UObject* UCommonUserWidgetFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
{return FactoryCreateNew(Class, InParent, Name, Flags, Context, Warn, NAME_None);
}#undef LOCTEXT_NAMESPACE

这样运行起来之后,会发现右键内容已经有了但是,名字不对,类型也不对,但是已经能正常创建出来了,因为我们还需要创建一个UAssetDefinitionDefault
在这里插入图片描述
在这里插入图片描述
.h

// Copyright Epic Games, Inc. All Rights Reserved.#pragma once
#include "CoreMinimal.h"
#include "AssetDefinitionDefault.h"#include "AssetDefinition_CommonWidgetBlueprint.generated.h"UCLASS()
class UAssetDefinition_CommonWidgetBlueprint : public UAssetDefinitionDefault
{GENERATED_BODY()public:UAssetDefinition_CommonWidgetBlueprint();virtual ~UAssetDefinition_CommonWidgetBlueprint() override;// UAssetDefinition Beginvirtual FText GetAssetDisplayName() const override;virtual FLinearColor GetAssetColor() const override;virtual TSoftClassPtr<UObject> GetAssetClass() const override;virtual TConstArrayView<FAssetCategoryPath> GetAssetCategories() const override;virtual EAssetCommandResult OpenAssets(const FAssetOpenArgs& OpenArgs) const override;virtual EAssetCommandResult PerformAssetDiff(const FAssetDiffArgs& DiffArgs) const override;virtual FText GetAssetDescription(const FAssetData& AssetData) const override;// UAssetDefinition End
};

.cpp

#include "AssetDefinition_CommonWidgetBlueprint.h"
#include "CommonWidgetBlueprint.h"
#include "WidgetBlueprintEditor.h"
#include "Misc/MessageDialog.h"
#include "SBlueprintDiff.h"#define LOCTEXT_NAMESPACE "AssetTypeActions"UAssetDefinition_CommonWidgetBlueprint::UAssetDefinition_CommonWidgetBlueprint() = default;UAssetDefinition_CommonWidgetBlueprint::~UAssetDefinition_CommonWidgetBlueprint() = default;FText UAssetDefinition_CommonWidgetBlueprint::GetAssetDisplayName() const
{return LOCTEXT("UAssetDefinition_CommonWidgetBlueprint", "Common Widget Blueprint");
}FLinearColor UAssetDefinition_CommonWidgetBlueprint::GetAssetColor() const
{return FLinearColor(FColor(44, 89, 180));
}TSoftClassPtr<> UAssetDefinition_CommonWidgetBlueprint::GetAssetClass() const
{return UCommonWidgetBlueprint::StaticClass();
}TConstArrayView<FAssetCategoryPath> UAssetDefinition_CommonWidgetBlueprint::GetAssetCategories() const
{static const TArray<FAssetCategoryPath, TFixedAllocator<1>> Categories = { EAssetCategoryPaths::UI };return Categories;
}EAssetCommandResult UAssetDefinition_CommonWidgetBlueprint::OpenAssets(const FAssetOpenArgs& OpenArgs) const
{EToolkitMode::Type Mode = OpenArgs.GetToolkitMode();EAssetCommandResult Result = EAssetCommandResult::Unhandled;for (UBlueprint* Blueprint : OpenArgs.LoadObjects<UBlueprint>()){if (Blueprint && Blueprint->SkeletonGeneratedClass && Blueprint->GeneratedClass){TSharedRef<FWidgetBlueprintEditor> NewBlueprintEditor(new FWidgetBlueprintEditor);const bool bShouldOpenInDefaultsMode = false;TArray<UBlueprint*> Blueprints;Blueprints.Add(Blueprint);NewBlueprintEditor->InitWidgetBlueprintEditor(Mode, OpenArgs.ToolkitHost, Blueprints, bShouldOpenInDefaultsMode);}else{FMessageDialog::Open( EAppMsgType::Ok, LOCTEXT("FailedToLoadWidgetBlueprint", "Widget Blueprint could not be loaded because it derives from an invalid class.\nCheck to make sure the parent class for this blueprint hasn't been removed!"));}Result = EAssetCommandResult::Handled;}return Result;
}EAssetCommandResult UAssetDefinition_CommonWidgetBlueprint::PerformAssetDiff(const FAssetDiffArgs& DiffArgs) const
{const UBlueprint* OldBlueprint = Cast<UBlueprint>(DiffArgs.OldAsset);const UBlueprint* NewBlueprint = Cast<UBlueprint>(DiffArgs.NewAsset);UClass* AssetClass = GetAssetClass().Get();SBlueprintDiff::CreateDiffWindow(OldBlueprint, NewBlueprint, DiffArgs.OldRevision, DiffArgs.NewRevision, AssetClass);return EAssetCommandResult::Handled;
}FText UAssetDefinition_CommonWidgetBlueprint::GetAssetDescription(const FAssetData& AssetData) const
{FString Description = AssetData.GetTagValueRef<FString>( GET_MEMBER_NAME_CHECKED( UBlueprint, BlueprintDescription ) );if ( !Description.IsEmpty() ){Description.ReplaceInline( TEXT( "\\n" ), TEXT( "\n" ) );return FText::FromString( MoveTemp(Description) );}return FText::GetEmpty();
}#undef LOCTEXT_NAMESPACE

这时候就得到了我们想要的结果:
在这里插入图片描述

往自己的UserWidget添加测试代码,发现能正常反射处理,因此此篇幅完成

在这里插入图片描述
在这里插入图片描述
对,别忘记添加Editor模块:

        "UnrealEd","UMGEditor", "UMG","AssetDefinition","Kismet",

Runtime模块:

        "UMG",  

在这里插入图片描述

当然完结了也没完全完,有人可能比较喜欢像我一样做一些明显的图标,便于选中,这里只需要添加Style就行:
Editor模块:

.h

// Copyright Epic Games, Inc. All Rights Reserved.#pragma once#include "Styling/SlateStyle.h"/** Manages the style which provides resources for niagara editor widgets. */
class FDivinePrologueEditorStyle : public FSlateStyleSet
{
public:static  void Register();static  void Unregister();static  void Shutdown();/** reloads textures used by slate renderer */static  void ReloadTextures();/** @return The Slate style set for niagara editor widgets */static  const FDivinePrologueEditorStyle& Get();static  void ReinitializeStyle();virtual const FName& GetStyleSetName() const override;private:	FDivinePrologueEditorStyle();void InitIcons();static TSharedPtr<FDivinePrologueEditorStyle> DivinePrologueEditorStyle;
};
.cpp
// Copyright Epic Games, Inc. All Rights Reserved.#include "DivinePrologueEditorStyle.h"
#include "Styling/SlateStyleMacros.h"
#include "Styling/SlateStyleRegistry.h"TSharedPtr<FDivinePrologueEditorStyle> FDivinePrologueEditorStyle::DivinePrologueEditorStyle = nullptr;void FDivinePrologueEditorStyle::Register()
{FSlateStyleRegistry::RegisterSlateStyle(Get());
}void FDivinePrologueEditorStyle::Unregister()
{FSlateStyleRegistry::UnRegisterSlateStyle(Get());
}void FDivinePrologueEditorStyle::Shutdown()
{Unregister();DivinePrologueEditorStyle.Reset();
}const FVector2D Icon8x8(8.0f, 8.0f);
const FVector2D Icon12x12(12.0f, 12.0f);
const FVector2D Icon16x16(16.0f, 16.0f);
const FVector2D Icon20x20(20.0f, 20.0f);
const FVector2D Icon32x32(32.0f, 32.0f);
const FVector2D Icon40x40(40.0f, 40.0f);
const FVector2D Icon64x64(64.0f, 64.0f);FDivinePrologueEditorStyle::FDivinePrologueEditorStyle() : FSlateStyleSet("DivinePrologueEditorStyle")
{FSlateStyleSet::SetContentRoot(FPaths::ProjectContentDir() / TEXT("StyleTextures"));FSlateStyleSet::SetCoreContentRoot(FPaths::ProjectContentDir() / TEXT("StyleTextures"));InitIcons();
}void FDivinePrologueEditorStyle::InitIcons()
{Set("CommonUserWidget.Icon", new IMAGE_BRUSH("Icon", Icon64x64));
}void FDivinePrologueEditorStyle::ReloadTextures()
{FSlateApplication::Get().GetRenderer()->ReloadTextureResources();
}const FDivinePrologueEditorStyle& FDivinePrologueEditorStyle::Get()
{if(!DivinePrologueEditorStyle.IsValid()){DivinePrologueEditorStyle = MakeShareable(new FDivinePrologueEditorStyle());}return *DivinePrologueEditorStyle;
}void FDivinePrologueEditorStyle::ReinitializeStyle()
{Unregister();DivinePrologueEditorStyle.Reset();Register();	
}const FName& FDivinePrologueEditorStyle::GetStyleSetName() const
{static FName StyleName("DivinePrologueEditorStyle");return StyleName;
}

这是我的路径:在这里插入图片描述
当然创建之后需要在模块启动时候注册它:
在这里插入图片描述
在UCommonUserWidgetFactory里面重载下面方法,返回我们Style里面对应的图片:

	virtual FName GetNewAssetThumbnailOverride() const override{return TEXT("CommonUserWidget.Icon");}

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

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

相关文章

Android 使用.9图 NinePatchDrawable实现动态聊天气泡

最近一段时间&#xff0c;在做一个需求&#xff0c;需要实现一个聊天气泡的动画效果&#xff0c;如下图所示&#xff1a; GitHub源码demo &#xff0c;建议下载demo&#xff0c;运行查看。 动态聊天气泡动画 静态聊天气泡 经过一段时间调研&#xff0c;实现方案如下: 实现方…

栈(定义,基本操作,顺序存储,链式存储)

目录 1.栈的定义1.重要术语2.特点 2.栈的基本操作3.栈的顺序存储1.顺序栈的定义2.基本操作1.初始化2.进栈3.出栈4.读栈顶 3.共享栈 4.栈的链式存储 1.栈的定义 栈( Stack&#xff09;是只允许在一端进行插入或删除操作的线性表。 一种受限的线性表&#xff0c;只能在栈顶进行插…

高校为什么需要大数据挖掘平台?

目前数据挖掘已经成为各种应用领域的重要技术&#xff0c;大学数据挖掘课程的开放已经出现。数据挖掘课程整合了多门学科知识。该课程包括各种理论知识&#xff0c;也离不开相关的实用技术。整个教学过程是培养和提高学生全面创新和解决问题的能力。过去&#xff0c;教学过程理…

Vscode禁止插件自动更新

由于电脑的vscode版本不是很新。2022.10月份的版本1.7.2&#xff0c;电脑vscode的python插件装的也是2022年4月份的某个版本&#xff0c;但插件经常自动更新&#xff0c;导致python代码无法Debug,解决办法&#xff1a; 点设置&#xff0c;搜autoUpdate, 把红色框选成无

MicroStation二次开发问题记录(1):打开项目时自动加载dll文件

环境配置 Windows10 MicroStation CE Update16 Visual Studio 2019 前言 开发好的dll文件若每次都需要在打开MS时单独加载&#xff0c;则过于繁琐&#xff0c;因此可以在确定的工程项目文件中进行一次设置&#xff0c;在打开该文件时自动加载 一、加载dll文件 1. 点击File—Se…

【模型推理优化学习笔记】CUDA加速矩阵乘计算

矩阵乘可以利用gpu多线程并行的特点进行加速计算&#xff0c;但是传统简单的方法需要多次读取数据到寄存器中&#xff0c;增加耗时&#xff0c;因此利用gpu的共享内存可以被一个block内的所有线程访问到的特性&#xff0c;结合tiling技术进行加速计算。 理论部分不解释了&#…

k8s ingress 代理 mysql 3306端口

helm 安装 ingress-nginx helm upgrade --install ingress-nginx ingress-nginx \--repo https://kubernetes.github.io/ingress-nginx \--namespace ingress-nginx --create-namespace执行命令 kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-ngin…

ROS学习笔记(5):ros_control

1.ros_control简介 ros_control - ROS Wiki ros_control是为ROS提供的机器人控制包&#xff0c;包含一系列控制器接口、传动装置接口、控制器工具箱等,有效帮助机器人应用功能包快速落地&#xff0c;提高开发效率。 2.ros_control框架 ros_control总体框架&#xff1a; 针对…

【微服务 Spring Cloud 6】服务如何拆分?使用微服务的注意事项?

目录 一、前言二、单体服务的弊端三、微服务化四、服务如何拆分&#xff1f;1、拆分原则2、拆分时机和拆分方法3、拆分实践 五、使用微服务的注意事项1、确保相关业务和利益相关者的支持2、确定微服务的拆分粒度3、遵循微服务架构的原则4、确保接口的稳定性5、关注数据一致性6、…

百数低代码与AI:实现业务智能化的新途径

今年6月&#xff0c;咨询机构麦肯锡发布了的一份题为《生成式人工智能的经济潜力》的研究报告&#xff0c;在报告中&#xff0c;分析师们通过对47个国家及地区的850种职业&#xff08;全球80%以上劳动人口&#xff09;的研究&#xff0c;探讨了在AI成指数级发展背后&#xff0c…

Shaderlab属性块

文档 官方文档 作用 参数显示在外部&#xff0c;可自定义调节。 语法 _Name(“Display Name”,type)defaultvalue _Name&#xff1a;必须使用下划线开始 Display Name:材质面板上显示的内容 type:属性的类型 dafaultvalue:类型的默认值 必须赋值 常用类型 Float:浮点数 …

PostgreSQL简介及安装步骤

PostgreSQL简介 PostgreSQL是一款开源的关系型数据库管理系统&#xff0c;具有强大的扩展性、高度的可定制性和可靠的稳定性&#xff0c;因此在企业级应用和开发领域中得到了广泛的应用。本文将介绍PostgreSQL的基本概念以及在各种操作系统上的安装步骤。 安装步骤 1. Window…

18、Flink的SQL 支持的操作和语法

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

05【保姆级】-GO语言的标识符

之前我学过C、Java、Python语言时总结的经验&#xff1a; 先建立整体框架&#xff0c;然后再去抠细节。先Know how&#xff0c;然后know why。先做出来&#xff0c;然后再去一点点研究&#xff0c;才会事半功倍。适当的囫囵吞枣。因为死抠某个知识点很浪费时间的。对于GO语言&a…

vscode + cmake + opencv example

nice try on macos CMakeLists.txt cmake_minimum_required(VERSION 3.20) #添加OPENCV库 #指定OpenCV版本&#xff0c;代码如下 #find_package(OpenCV 3.3 REQUIRED) #如果不需要指定OpenCV版本&#xff0c;代码如下 find_package(OpenCV REQUIRED)#添加OpenCV头文件 includ…

智能语音和自然语言处理技术

一、定义 智能语音和自然语言处理技术是指通过计算机技术实现人机交互的一种技术。它可以让计算机和人类之间进行自然而流畅的交流&#xff0c;从而实现更高效、更便捷、更智能的信息交流和处理。 智能语音和自然语言处理技术主要包括语音识别、语音合成、自然语言理解、自然…

CRM客户管理系统究竟是什么?如何实施?

很多销售人员都不是特别喜欢使用信息化软件&#xff0c;然而从销售经理的角度看&#xff0c;信息化又的确提升了团队的管理效率和业绩。追究这些矛盾的原因&#xff0c;无外乎几点&#xff1a; 认知角度 → 销售员&#xff1a;数据没用又浪费我时间 VS 销售经理&#xff1a;数…

openssl交叉编译 (ubuntu+arm)

1.下载安装包 wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz 2.解压安装包 tar -zxvf openssl-1.1.1l.tar.gz 3.进入源码文件夹-修改编译器 CCarm-linux-gnueabihf-gcc 4.配置编译参数 ./config no-asm -shared --prefix/home/alientek/sp_test/openssl/sp…

Springboot 集成 mongodb

一、引入依赖 1.1 Maven <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> 二、yml 配置文件 data:mongodb:# 基础链接参数# 连接的库database: mongo…

单例模式读取配置文件

单例模式&#xff08;Singleton Pattern&#xff09;是一种常见的设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点以获取该实例。当你需要在应用程序中读取配置文件时&#xff0c;使用单例模式可以确保你只创建一个配置对象&#xff0c;以避免重…