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语言:从入门到精通 数据…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
