Create UI elements at runtime

Hello,

as I am coming from other GUI frameworks (like QT for Python) I am accustomed to create sometimes UI elementds also via code. I am wondering if this is possibile with Xojo too.

So I have started with some experimentation and added the following code to the Pressed handler of a DesktopButton:

var win as new DesktopWindow
var btn as new DesktopButton

btn.Caption = "push me"
btn.Left = 50
btn.Top = 80
btn.Width = 150

win.Title = "Hello Window"
win.Top = 100
win.Resizeable = true
win.HasCloseButton = true
win.HasFullScreenButton = true
win.HasMinimizeButton = true
win.Type = Types.Document

win.Width = 600
win.Height = 400

win.AddControl(btn)

win.Show

Once I run this, a new DesktopWindow is created, but I don’t get the close, minimize, fullscreen buttons.
I am also wondering if there are other ways to pass properties to the DesktopWindow and DesktopButton constructor, instead of manually setting every single property after instance creation.

Finally I was not able to add an event handler to the DesktopButton. I have tried with the AddHandler keyword, but I have got a syntax error message, using the following code:


Sub onClose(sender as DesktopButton)
  win.Close
end Sub

AddHandler btn.Pressed, AddressOf onClose

Does Xojo has a constructor like closure in Swift/anonymous function in JavaScript/lambda in Python?

Thank you in advance

It is not possible, the doc saids :
Window.HasFullScreenButton
…
Notes
This property can only be changed at design-time.
idem for Maximize and Minimise buttons and other properties.

1 Like

A window must be created in the IDE.

Controls within the window can be created on the fly.

1 Like

Thank you @Eric_Pousse @Kem_Tekinay for the answers.

Nothing stops you adding your own Constructor method and adding all those initialisations there.

Can you give me more details to better understand please?

When I create a new Window in the IDE, I see it assign to it the Super property to DesktopWindow, but I don’t get if it create a class that inherits from it. I noticed in the debugger a Window1.Window1 type.
So does Window1 is an instance of the class DesktopWindow or of the class Window1 that Xojo creates behind the scene?

If I want to create my own CustomWindow class how can I do that?

Finally, how can I attach event handlers to controls via code?

thank you

As for the window, you cant have a DesktopWindow class in xojo, you have to create a subclass that inherits from it. Go to INSERT and choose window. This is the new Subclass. You have to disable the Implicit instance so it is not created by default.

Then you can do:

Dim w As Window1
w.show

Technically you can sort of create controls at runtime but nothing like you do in other languajes, UI in xojo is meant to be all by drag and drop. but is better if you check the documentation to learn the basics:

https://docs.xojo.com/

Dont look for tutorials or videos older than a year because all of them are outdated and will confuse you.

Then you add a method called Constructor to your new class, Window1, and add your initialisation statements there.

1 Like

Ok thank you all, I did a bunch of tests and together with your replies I think I have got it.

So DesktopWindow is a special class. What I see in the Navigation panel, for example, Window1 is the name of a class that inherits from DesktopWindow. But if I have the flag “Implicit Instance” on, Window1 is also the name of an instance of type Window1, and I can call any method directly on it.
Am I correct?

The only minor thing that haven’t clear now is why in the debugger I see Window1.Window1 as type name. I have used also the GetTypeInfo function and I see that Window1.Window1 is the fullname of the Window1 class. So the only explanation I have is that the first Window1 is a kind of namespace prefix.

Do Xojo support namespacing for class names?

thx

its more like

var win as new MyDesktopWindow

a template window you created in the ide with name MyDesktopWindow and super to DesktopWindow

why new DesktopWindow does not work as expexted i don’t know.

Actually I was able to instantiate a new DesktopWindow and show it as expected. I cannot change its properties as I discovered they are read-only properties. I was able to add dynamically controls with the AddControl method.

I don’t know how to add dynamically event handler to controls though.

example in a button pressed for a test it create a button at runtime

Var btn As New DesktopButton

btn.Caption = "push me"
btn.Left = 50
btn.Top = 80
btn.Width = 150
btn.Height = 32
btn.Visible = True
btn.Enabled = True

Self.AddControl btn

AddHandler btn.Pressed, AddressOf onClose

this close the window, a method inside of the window

Public Sub onClose(sender as DesktopButton)
 ' sender.Caption = "YES"
'Self.Maximize
Self.Close
  
End Sub

if you use AddHandler use also RemoveHandler

I cannot change its properties

oh ok, please make a feedback that locked properties can be given in a extra constructor
because you not want use the form designer and have to create a form at runtime.
(unlocked properties would be a better option.)

2 Likes

Ok thank you the AddHandler now works if I add the method to a window created via the form designer.

However I am still puzzled about some settings in the Inspector. If I inspect a Window, the Name attribute refers to the name of the class, and if I have the option to implicit create the instance, it’s also the instance name. So just to summarize, in this case Window1 is an instance of the class Window1 that inherits from DesktopButton, the superclass.

However if I have a look to a Button:

here Button1 is the instance name. Is DesktopButton its class or its superclass? the inspector says the latter, so what is Button1 's class name/type that in turn inherits from DesktopButton?

So what the Name property defines? is the instance name or the class name of a UI Control?

It’s its superclass. Can yoiu rephrase your second question as I can’t parse it.

thank you, and sorry for the second question, I edited it now, but let me reformulate it:

what is the base class of the instance Button1, the same base class that inherits from DesktopButton superclass?

Not sure if I am wrong, but I think instead DesktopButton should be referred as the base class of the Button1 instance

Weird but yes.

For controls is the instance name. for a implicit instance window is both

1 Like

with implicit instance on you can use a single instance without using new
something like Window1.Show
but better is creating an object like

var w as new Window1
w.Show

a Button1 is somehow a sub class with all features from parent/super class.
if you use only one super class its like a base class with common things.

thank you @Ivan_Tellez.

So similarly I think “Super” has a different meaning for windows and control.
For windows, super refers to its superclass
For controls, super refer to its baseclass

am I wrong?

you can see the class hirachy in documentation right top.

YourButton<-DesktopButton<-DesktopUIControl<-DesktopControl<-Object
YourWindow<-DesktopWindow<-Object

in Xojo if you create a class Class1
and add a Shared Method you can access it with
Class1.MyMethod
similar to implicit instance at Windows

so in my case, YourButton is the base class of Button1 instance?
what do you mean by Button1 is somehow a sub class? Button1 should be the instance name
I am confused now

Forum for Xojo Programming Language and IDE. Copyright © 2021 Xojo, Inc.