A possible bug in 4.27.2 about Slate UI

I am working with a project with Slate UI and am currently using UE 4.27.2. After I made some classes in my original project, the game always crashed with access violation to address 0x80 after I tried to add a widget to the viewport. I figured out later that this was because that a class was directly inherited from SButton.

I made another project, a minimal example that would show this problem. First I created an empty C++ project. Then I added a Slate Widget class, as shown below:

SMyButton.h

#pragma once

#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"

/**
 * 
 */
class SBUTTONBUG_API SMyButton : public SButton
{
public:
	SLATE_BEGIN_ARGS(SMyButton)
	{}
	SLATE_END_ARGS()

	/** Constructs this widget with InArgs */
	void Construct(const FArguments& InArgs);
};

SMyButton.cpp

#include "SMyButton.h"
#include "SlateOptMacros.h"

BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SMyButton::Construct(const FArguments& InArgs)
{
	/*
	ChildSlot
	[
		// Populate the widget
	];
	*/
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

In this example, then I created a Level Script Actor to add this widget directly to the viewport at the beginning of the level. I overloaded its BeginPlay method to add the following code

void AMyLevelScriptActor::BeginPlay()
{
	if (GEngine && GEngine->GameViewport)
	{
		GEngine->GameViewport->AddViewportWidgetContent(SAssignNew(button, SMyButton));
		FSlateApplication::Get().SetKeyboardFocus(button, EFocusCause::SetDirectly);
	}
}

, where button is defined as a private shared pointer to SMyButton in the header file

	TSharedPtr<class SMyButton> button;

I also tried other methods to add the inherited button to the viewport, including,

  1. Add it to the viewport in BeginPlay() of the Game Mode
  2. Make the button a child of some other widgets (In my original project, I put it inside a slot of a VerticalBox, and put the VBox in another layer) and add this covering widget to the viewport
  3. Add some contents to the inherited button before adding it to the viewport

And all of them gave the same problem.

A screenshot at when the problem occurred is shown below


Here’s another screenshot at when the problem occurred in debug mode

I highly suspect this is a bug because it looked like a nullptr had been passed and was accessed (with some adjustment, probably a cast) because the address was always 0x80. Also, in debug mode, the code that caused the error could not be shown. It is not inside the SButton source code that I could see, but some compiled module of the engine.

But I am not very sure (maybe I should not inherit from SButton directly, but the documentation not says so), so I ask this question here.

I found that the comment of SWidget says that do not inherit from it. And it explicitly allows the inheritance from LeafWidget or Panel (and we know that we can inherit from SCompoundWidget).

Also previously I made a class directly from SVerticalBox, which worked fine. So I don’t know if SButton is special or it is simply a problem.

1 Like

When it comes to Slate, god knows :man_shrugging:

I don’t know if it will help with your problem, but in your actual code do you call SButton::Construct from within your SMyButton::Construct function?

I didn’t, and adding a call to SButton::Construct exactly solved my problem! Thanks a lot.

By the way, I didn’t know much about how internally Slate construction works. Could you spare sometime and explain a little to me? I thought that Construct is automatically called for base class by some mechanism, but which turned out to be not this way. Thank you in advance for your time.

1 Like