当前位置: 首页 > news >正文

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");}

相关文章:

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

前言&#xff1a; 为了实现与UserWidget一致的右键添加&#xff0c;便有了此章 注&#xff1a;这里使用的是UE5.3 目标内容&#xff1a; 这里可以参考UserWidget的源码&#xff0c;拷贝一份属于自己的就ok&#xff08;本篇章只是全改成了属于自己的CommonUserWidget&#xff…...

三级缓存【又称提前暴露(early exposure)】

三级缓存是Spring框架用于解决循环依赖问题的一种机制。它用于管理正在被创建的Bean实例&#xff0c;以确保它们在适当的时候被正确初始化。三级缓存分为三个阶段&#xff0c;分别是"未暴露"、"已暴露"和"已完成"&#xff0c;以下是它们的解释&a…...

【ARM Coresight 系列文章 3.5 - ARM Coresight -- JTAG-DP(JTAG Debug Port) 详细介绍】

请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】 文章目录 概述1.1 DP elements1.1.1 外部连接到 JTAG-DP上的信号1.1.2 Debug TAP 状态机1.2 指令扫描链和指令1.3 DPv3 JTAG-DP 访问AP示意图概述 本节内容主要介绍 JTAG Debug Port 、Debug Test Access Port (DBGTAP), D…...

【笔记】回顾JavaWeb结合自身开发的项目——分层解耦与IOC、MySQL简单查询

分层解耦的三层架构 如下图所示是手术训练系统中的实现&#xff1a; 如果你需要从new EmpServiceA()变为new EmpServiceB()&#xff0c;那么必然需要修改Service和Controller层的代码&#xff0c;那么如果我们不new 这个对象呢&#xff1f;是不是就不需要依赖Controller层。 …...

Modelsim 使用教程(5)——Analyzing Waveforms

一、概述 Wave窗口允许我们以HDL波形和数据的形式查看仿真结果。Wave窗口被划分为多个窗格。通过单击并在任意两个窗格之间拖动该条&#xff0c;可以调整路径名窗格、值窗格和波形窗格的大小。 二、加载一个设计&#xff08;Loading a Design&#xff09; 1、打开modelsim 2、…...

String-固长字符串序列

在java中&#xff0c;String不是基础数据类型&#xff0c;也不是包装器类型&#xff0c;其实它是为了便捷操作字符、字节等而诞生的引用数据类型。更多内容详见公众hao&#xff1a;云水致诚 1、String是基础数据类型吗&#xff1f; String不是基础类型&#xff0c;存储在其中的…...

RABC权限模型与Spring Security

今天&#xff0c;我将带你进入一个充满策略和刺激的领域——权限之战。在这场战斗中&#xff0c;我们的主角是RABC权限模型&#xff08;Role-Based Access Control&#xff09;和Spring Security&#xff0c;他们将共同为我们打造一个安全稳定的世界。 权限模型&#xff1a;游戏…...

linux 编译lpthread

1&#xff1a;undefined reference to pthread_create gcc main.c -o test -lpthread [roothqgao ddserver]# gcc ddserver.c -o ddserver -lpthread [roothqgao ddserver]# ./ddserver Segmentation fault makefile 简单例子 all: httpd client LIBS -lpthread #-lsocket h…...

工业自动化工厂PLC远程控制网关物联网应用

远程控制网关在工厂自动化领域中起到了至关重要的作用&#xff0c;特别是在工厂PLC数据通讯方面。它充当着数据传输的桥梁&#xff0c;连接了工厂中的各类设备和系统&#xff0c;实现了远程监控和控制的功能。本文将详细介绍远程控制网关在工厂PLC数据通讯中的应用。 远程控制网…...

Nginx 实现负载均衡

目录 一&#xff1a;负载均衡介绍 二、 负载均衡具备的功能 1.提高服务器性能 2.提高系统可用性 3.提高系统的可伸缩性 4.实现流量均衡 三、示例配置&#xff0c;如何使用nginx实现负载均衡 四、负载均衡策略配置 1.基于轮询的负载均衡&#xff08;默认&#…...

浅谈测试需求分析

一、什么是需求分析 小编理解的需求分析就是要弄清楚用户需要的是什么功能&#xff0c;用户会怎样使用系统。这样测试时才能更清楚的知道系统该怎么样运行&#xff0c;才能更好的设计测试用例&#xff0c;才能更好的测试。 测试需求分析是测试工作的第一步&#xff0c;经过需…...

18、Python的编码规范:PEP 8介绍及基本遵循原则

文章目录 PEP 8简介基本遵循原则1. 缩进2. 行宽3. 空行4. 导入5. 空格6. 命名约定7. 表达式和语句中的空格8. 注释9. 编码声明10. 文档字符串PEP 8简介 PEP 8,或Python Enhancement Proposal 8,是一个官方文档,发布于2001年。它由Guido van Rossum,Python语言的创始人,以…...

AI:48-基于卷积神经网络的气象图像识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌本专栏包含以下学习方向: 机器学习、深度学…...

AI:64-基于深度学习的口罩佩戴检测

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…...

Time series analysis of InSAR data: Methods and trends(NASA,2015)

文章目录 ISPRS J PHOTOGRAMMIntroductionPhase unwrapping相位解缠算法综述 Time series analysis of InSAR dataPersistent Scatterer Interferometry (PSI)--持久散射体☆☆☆☆PSInSAR && SBAS-InSAR☆☆☆☆PS-InSARSBAS-InSARDS-InSAR&#xff08;分布式散射体干…...

视频集中存储/云存储EasyCVR启动后查询端口是否被占用出错,该如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…...

【JMeter】后置处理器的分类以及场景介绍

1.常用后置处理器的分类 Json提取器 针对响应体的返回结果是json格式的会自动生成新的变量名为【提取器中变量名_MatchNr】,取到的个数由jsonpath expression取到的个数决定 可以当作普通变量调用,调用语法:${提取器中变量名_MatchNr}正则表达式提取器 返回结果是任何数据格…...

即时通讯技术文集(第22期):IM安全相关文章(Part1) [共13篇]

​为了更好地分类阅读 52im.net 总计1000多篇精编文章&#xff0c;我将在每周三推送新的一期技术文集&#xff0c;本次是第22 期。 [- 1 -] 即时通讯安全篇&#xff08;一&#xff09;&#xff1a;正确地理解和使用Android端加密算法 [链接] http://www.52im.net/thread-216-1…...

Node Sass version 9.0.0 is incompatible with ^4.0.0.

1.错误产生原因&#xff1a; node、 node-sass 和sass-loader的版本对应问题 2.解决方案&#xff1a; 删除之前的 npm uninstall node-sass sass-loader 安装指定的 npm i node-sass4.14.1 sass-loader7.3.1 --save -dev...

【STL】:list的模拟实现

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关list的模拟实现&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...