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

news2024/11/23 21:41:43

前言:

为了实现与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 created
	UPROPERTY(EditAnywhere, Category=WidgetBlueprintFactory)
	TEnumAsByte<enum EBlueprintType> BlueprintType;

	// The parent class of the created blueprint
	UPROPERTY(EditAnywhere, Category=WidgetBlueprintFactory, meta=(AllowAbstract = ""))
	TSubclassOf<class UUserWidget> ParentClass;

	//~ Begin UFactory Interface
	virtual 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 options
		FClassViewerInitializationOptions 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 picker
		FClassViewerModule& ClassViewerModule = FModuleManager::LoadModuleChecked<FClassViewerModule>("ClassViewer");

		// Fill in options
		FClassViewerInitializationOptions 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 one
	check(Class->IsChildOf(UCommonWidgetBlueprint::StaticClass()));

	UClass* CurrentParentClass = ParentClass;
	if (CurrentParentClass == nullptr)
	{
		CurrentParentClass = UCommonUserWidget::StaticClass();
	}

	// If they selected an interface, force the parent class to be UInterface
	if (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 project
		if ( 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 Begin
	virtual 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.coloradmin.cn/o/1181879.html

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

相关文章

定时发圈怎么设置?

微信本身是不能定时发送朋友圈的。微信公众号可以定时发送&#xff0c;微博可以定时发送&#xff0c;那微信可不可以也定时发送呢&#xff1f;当然可以&#xff0c;只要用这个方法&#xff0c;微信也能实现定时发朋友圈&#xff0c;不用再守着时间发朋友圈了。

USB HID在系统下通信的一些总结

前言 这篇文章主要介绍在PC&#xff08;上位机&#xff0c;Host&#xff09;端&#xff0c;通过HID与硬件进行通信的一些总结&#xff0c;像很多同学肯定和我一样压根不想 去了解什么USB相关的资料&#xff0c;毕竟USB太复杂了&#xff0c;只想有个API给我们进行下数据就好了&…

3D视觉引导纸箱拆码垛,助力物流行业转型升级

近年来&#xff0c;自动化和智能化技术在各行业的应用越来越广泛&#xff0c;特别是在物流和仓储领域。纸箱拆码垛是物流仓储中的一个重要环节。 人工分拣效率低、错误率高、成本高&#xff0c;传统的拆码垛设备存在兼容性差&#xff0c;对纸箱的识别率不高、操作不灵活等问题…

【分布式事务】初步探索分布式事务的概率和理论,初识分布式事的解决方案 Seata,TC 服务的部署以及微服务集成 Seata

文章目录 一、分布式服务案例1.1 分布式服务 demo1.2 演示分布式事务问题 二、分布式事务的概念和理论2.1 什么是分布式事务2.2 CAP 定理2.3 BASE 理论2.4 分布式事务模型 三、分布式事务解决方案 —— Seata3.1 什么是 Seata3.2 Seata 的架构3.3 Seata 的四种分布式事务解决方…

渗透实战靶机2wp

0x00 简介 1、测试环境 目标IP&#xff1a;10.xxxx 测试IP&#xff1a;192.168.139.128 测试环境&#xff1a;win10、kali等 测试时间&#xff1a;2021.7.22-2021.7.22 测试人员&#xff1a;ruanruan 2、测试过程 本次实战主要通过对收集到的端口、目录等信息进行持续整…

​怎么测试websocket接口

在部分业务中&#xff0c;我们需要使用长连接&#xff0c;我们可以使用http长连接或者websocket&#xff0c;开发结束后难免会遇到测试问题&#xff0c;这里推荐2个&#xff0c;一个是postman&#xff0c;一个是网站 postman 测试网站 测这边推荐测试网站&#xff0c;支持ws/w…

赴日工作赴日IT 如何找到一份日本IT工作?

IT在日本属于普通白领工作&#xff0c;那些想靠IT工作发财就不必考虑了。但是靠IT工作能安安稳稳的过个自己的小日子没问题&#xff0c;买房买车问题不大&#xff0c;作为一个普通人&#xff0c;在日本可以过的比较舒服。对有在日本长期发展的打算的还算是一个比较好的方向&…

Vue创建浅层响应式数据

shallowReactive&#xff1a;只处理对象第一层数据的响应式&#xff08;浅响应式&#xff09;。 shallowRef&#xff1a;只处理基本数据类型的响应式&#xff0c;不处理对象类型的响应式。 shallowReactive 适用于&#xff1a;如果有一个对象类型的数据&#xff0c;结构比较深…

【软考】2023下半年系统集成项目管理工程师案例分析真题(第五批次)

2023下半年系统集成项目管理工程师案例分析真题&#xff08;第五批次&#xff09; 案例一 (17分)-配置管理案例二 &#xff08;20分&#xff09;-进度管理案例三 &#xff08;18分&#xff09;-风险管理案例四 - 人力资源管理 系列文章版本记录 案例一 (17分)-配置管理 某游戏公…

【Spring】@Component组件

大前提&#xff1a; 添加了相关的约束文件以及注解支持 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:…

理解JavaScript模运算符

本文翻译自 Understanding the JavaScript Modulo Operator&#xff0c;作者&#xff1a;joshwcomeau&#xff0c; 略有删改。 当我第一次学习编码时&#xff0c;我记得发现模运算符&#xff08;%&#xff09;非常令人困惑。&#x1f62c; 当你不明白它的原理的时候&#xff0…

深度学习之基于YoloV5-Deepsort人物识别与追踪系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 YoloV5-Deepsort是一种基于深度学习的人物识别与追踪系统&#xff0c;具有较高的准确率和实时性能。 YoloV5是一种…

4.三大基础排序 -选择排序、冒泡排序、插入排序

排序算法 文章目录 冒泡排序算法步骤动图代码优化总结 选择排序算法步骤动图代码总结 插入排序算法步骤动图代码总结 排序算法&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。一般默认排序是按照由小到大即…

2.HTML中常用浏览器

2.常用浏览器 2.1 什么是浏览器 浏览器是网页显示&#xff0c;运行的平台。常用的浏览器有IE&#xff0c;火狐&#xff0c;谷歌&#xff0c;Safari和Opera等 平时成为五大浏览器 2.2 浏览器内核 浏览器内核&#xff08;渲染引擎&#xff09;&#xff1a;负责读取网页内容&…

用CMake编译项目 CMake和g++的区别

0.同样是编译c文件有了g为什么又出了个CMake&#xff1f; g适用于要编译的文件较少的情况。 而CMake像是写好的脚本&#xff0c;可以一键编译很多c文件。一.创建项目和CMakeLists.txt文件 1.1 创建一个项目&#xff0c;目录结构如下 1.2 在项目的根目录下创建一个CMakeLists.…

个人常用Linux命令

来自 linux命令学习-2023-8-1 153913.md等 1、切换目录 cd //切换目录 cd change directory cd 目录名 cd .. 返回上一级目录 pwd显示当前所处目录cd 绝对路径 cd ~ 表示一个用户的home目录 cd - 表示上一次访问的目录 cd / 表示进入根目录下//新建目录/data,并且进入/data…

001、Nvidia Jetson Nano Developer KIT(b01)-系统与登录

之——镜像烧录与远程登录 杂谈 Nvidia Jetson Nano Developer KIT&#xff08;b01&#xff0c;4G&#xff09;&#xff0c;系统配置全纪录&#xff0c;镜像烧录、系统安装、远程桌面安装、cuda与torch安装、pycharm、pycuda、tensorrt等等。 正文 1.开发板系统安装 1.1 开发…

创意涌动:CSDN·大学生博主14天创作挑战赛·第二期,正式开启报名!

文章目录 ⭐️ 活动介绍⭐️ 活动详情⭐️ 活动奖品⭐️ 活动流程⭐️ 评审规则⭐️ 报名&投稿注意事项⭐️ 关于活动官方 活动报名地址&#xff08;点击跳转&#xff09; 本次活动与官方活动及其他博主的创作型活动并不不冲突&#xff01; ⭐️ 活动介绍 亲爱的大学生博主…

【无标题】【教3妹学编程-算法题】2918. 数组的最小相等和

3妹&#xff1a;呜呜&#xff0c;烦死了&#xff0c; 脸上长了一个痘 2哥 : 不要在意这些细节嘛&#xff0c;不用管它&#xff0c;过两天自然不就好了。 3妹&#xff1a;切&#xff0c;你不懂&#xff0c;影响这两天的心情哇。 2哥 : 我看你是不急着找工作了啊&#xff0c; 工作…

Leo赠书活动-05期 【打造敏捷测试团队】文末送书5本

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…