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添加到对应菜单栏
前言: 为了实现与UserWidget一致的右键添加,便有了此章 注:这里使用的是UE5.3 目标内容: 这里可以参考UserWidget的源码,拷贝一份属于自己的就ok(本篇章只是全改成了属于自己的CommonUserWidgetÿ…...
三级缓存【又称提前暴露(early exposure)】
三级缓存是Spring框架用于解决循环依赖问题的一种机制。它用于管理正在被创建的Bean实例,以确保它们在适当的时候被正确初始化。三级缓存分为三个阶段,分别是"未暴露"、"已暴露"和"已完成",以下是它们的解释&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简单查询
分层解耦的三层架构 如下图所示是手术训练系统中的实现: 如果你需要从new EmpServiceA()变为new EmpServiceB(),那么必然需要修改Service和Controller层的代码,那么如果我们不new 这个对象呢?是不是就不需要依赖Controller层。 …...
Modelsim 使用教程(5)——Analyzing Waveforms
一、概述 Wave窗口允许我们以HDL波形和数据的形式查看仿真结果。Wave窗口被划分为多个窗格。通过单击并在任意两个窗格之间拖动该条,可以调整路径名窗格、值窗格和波形窗格的大小。 二、加载一个设计(Loading a Design) 1、打开modelsim 2、…...
String-固长字符串序列
在java中,String不是基础数据类型,也不是包装器类型,其实它是为了便捷操作字符、字节等而诞生的引用数据类型。更多内容详见公众hao:云水致诚 1、String是基础数据类型吗? String不是基础类型,存储在其中的…...
RABC权限模型与Spring Security
今天,我将带你进入一个充满策略和刺激的领域——权限之战。在这场战斗中,我们的主角是RABC权限模型(Role-Based Access Control)和Spring Security,他们将共同为我们打造一个安全稳定的世界。 权限模型:游戏…...
linux 编译lpthread
1: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远程控制网关物联网应用
远程控制网关在工厂自动化领域中起到了至关重要的作用,特别是在工厂PLC数据通讯方面。它充当着数据传输的桥梁,连接了工厂中的各类设备和系统,实现了远程监控和控制的功能。本文将详细介绍远程控制网关在工厂PLC数据通讯中的应用。 远程控制网…...
Nginx 实现负载均衡
目录 一:负载均衡介绍 二、 负载均衡具备的功能 1.提高服务器性能 2.提高系统可用性 3.提高系统的可伸缩性 4.实现流量均衡 三、示例配置,如何使用nginx实现负载均衡 四、负载均衡策略配置 1.基于轮询的负载均衡(默认&#…...
浅谈测试需求分析
一、什么是需求分析 小编理解的需求分析就是要弄清楚用户需要的是什么功能,用户会怎样使用系统。这样测试时才能更清楚的知道系统该怎么样运行,才能更好的设计测试用例,才能更好的测试。 测试需求分析是测试工作的第一步,经过需…...
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(分布式散射体干…...
视频集中存储/云存储EasyCVR启动后查询端口是否被占用出错,该如何解决?
安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…...
【JMeter】后置处理器的分类以及场景介绍
1.常用后置处理器的分类 Json提取器 针对响应体的返回结果是json格式的会自动生成新的变量名为【提取器中变量名_MatchNr】,取到的个数由jsonpath expression取到的个数决定 可以当作普通变量调用,调用语法:${提取器中变量名_MatchNr}正则表达式提取器 返回结果是任何数据格…...
即时通讯技术文集(第22期):IM安全相关文章(Part1) [共13篇]
为了更好地分类阅读 52im.net 总计1000多篇精编文章,我将在每周三推送新的一期技术文集,本次是第22 期。 [- 1 -] 即时通讯安全篇(一):正确地理解和使用Android端加密算法 [链接] http://www.52im.net/thread-216-1…...
Node Sass version 9.0.0 is incompatible with ^4.0.0.
1.错误产生原因: node、 node-sass 和sass-loader的版本对应问题 2.解决方案: 删除之前的 npm uninstall node-sass sass-loader 安装指定的 npm i node-sass4.14.1 sass-loader7.3.1 --save -dev...
【STL】:list的模拟实现
朋友们、伙计们,我们又见面了,本期来给大家解读一下有关list的模拟实现,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏:C语言:从入门到精通 数据…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
