void Construct( const FArguments& Args ) { SetCanTick(false); this->ChildSlot [ SNew(SVerticalBox) + SVerticalBox::Slot() .Padding( FMargin( 0.0f, 0.0f, 2.0f, 0.0f ) ) [ FSlateApplicationBase::Get().MakeImage( FSlateApplicationBase::Get().GetAppIcon(), Args._IconColorAndOpacity, EVisibility::HitTestInvisible ) ] ]; }
slate代码这样写的,一开始学感觉很奇怪
其实这是为了减少代码而设计的.
首先这个widget继承自SCompoundWidget,这个可以有子控件,SCompoundWidget继承自SWidget,这个SWidget是基础的控件,它不可以有子控件
SCompoundWidget里面有成员 ChildSlot ,是这样定义的 FSimpleSlot ChildSlot; 这个是子控件容器
/** A slot that support alignment of content and padding */ class SLATECORE_API FSimpleSlot : public TSupportsOneChildMixin<FSimpleSlot>, public TSupportsContentAlignmentMixin<FSimpleSlot>, public TSupportsContentPaddingMixin<FSimpleSlot> { public: FSimpleSlot(SWidget* InParent) : TSupportsOneChildMixin<FSimpleSlot>(InParent) , TSupportsContentAlignmentMixin<FSimpleSlot>(HAlign_Fill, VAlign_Fill) { } };
下面是TSupportsOneChildMixin定义
/** * Widgets that will only have one child can return an instance of FOneChild. */ template <typename MixedIntoType> class TSupportsOneChildMixin : public FChildren, public TSlotBase<MixedIntoType> { public: TSupportsOneChildMixin(SWidget* InOwner) : FChildren(InOwner) , TSlotBase<MixedIntoType>() { this->RawParentPtr = InOwner; } virtual int32 Num() const override { return 1; } virtual TSharedRef<SWidget> GetChildAt( int32 ChildIndex ) override { check(ChildIndex == 0); return FSlotBase::GetWidget(); } virtual TSharedRef<const SWidget> GetChildAt( int32 ChildIndex ) const override { check(ChildIndex == 0); return FSlotBase::GetWidget(); } private: virtual const FSlotBase& GetSlotAt(int32 ChildIndex) const override { check(ChildIndex == 0); return *this; } };
而TSlotBase有重写[] 方法
template<typename SlotType> class TSlotBase : public FSlotBase { public: TSlotBase() : FSlotBase() {} TSlotBase( const TSharedRef<SWidget>& InWidget ) : FSlotBase( InWidget ) {} SlotType& operator[]( const TSharedRef<SWidget>& InChildWidget ) { this->AttachWidget(InChildWidget); return (SlotType&)(*this); } SlotType& Expose( SlotType*& OutVarToInit ) { OutVarToInit = (SlotType*)this; return (SlotType&)(*this); } };
所以有上面那个方括号里面写代码的内容,意思就是方括号里面的widget 加到子控件数组里