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语言:从入门到精通 数据…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
