Hello, I am new to OOP and Python but I have 15 years + in C programming in a former life, so kind of a newbie as far as OOP is concerned… I think I understand OOP theoretically (somewhat) but I am finding the procedural to OOP jump difficult in practice…
One thing that I am trying to understand is why am I editing a Class directly, e.g. “class Form1(Form1Template):” surely the class was created by you folk and I should be passing parameters into my own instance of that class, not messing with the class directly? Not sure if this sounds like a dumb question but its been bugging me for weeks… I though the class is a ‘template’ and the instance is my version of that template filled out i.e. the object instance which is then executed? right?
Look forward to your reply. Thanks
To tell your instances
- how you want them to behave, e.g., what to do when someone clicks the “Save” button you added in the IDE, and
- what additional information they will keep on-hand (as member variables) in order to support such behavior, e.g., the specific values to be saved, and where to save them.
One approach would be for Anvil to provide a Form
class that allows to add buttons, labels, etc.
Another approach would be for Anvil to provide a FormTemplate
class able to manage the basics of being a form. Then leave it to you to create the class MyForm
derived from FormTemplate
and add more members to it. The resulting MyForm
will be a class with all the basic features derived from FormTemplate
, plus anything you added to it.
If you look at how each form is defined, you will find:
from ._anvil_designer import MyFormTemplate
class MyForm(MyFormTemplate):
This means that Anvil will create a template class under the hood called MyFormTemplate
and setup an empty class MyForm
where you can add all your methods. Perhaps under under the hood MyFormTemplate
is derived from a more generic FormTemplate
, but we don’t care. All we care is that MyForm
has all the methods and properties derived from MyFormTemplate
plus all the ones that you will be adding.
You can create a form that takes arguments in the constructor and add your own members, something like:
class MyForm(MyFormTemplate):
def __init__(self, generating_pdf=False, default_settings=None, **properties):
self.generating_pdf = generating_pdf
self.default_settings = default_settings or {}
def show_only_third_button(self):
self.button_1.visible = self.button_2.visible = False
self.button_3.visible = True
At this point you can use both MyForm.add_components()
defined in MyFormTemplate
and MyForm.show_only_third_button()
defined by you.
And use it either in an alert
or to generate a PDF:
# on the client
alert(MyForm())
# on a server module
settings = {<something here>}
anvil.pdf.render_form('MyForm', generating_pdf=True, default_settings=settings)
If you think functional, the C way, you would need functions able to do stuff with the form template MyForm
.
If you think OO, the Python way, you teach the class how to do stuff, you instantiate an object of that class, and tell that object what to do.
Thanks for your detailed response and describing inheritance from FormTemplate class to MyForm class - I suppose when we hit run, the anvil engine creates the required instances for execution…
You can create a new instance of a form yourself, for example when you want to show the form inside an alert, with alert(MyForm())
, or when you want to add it to a container in an existing form, with self.column_panel_1.add_component(MyForm())
.
And in some cases Anvil will do that automatically.
You could also do silly things like:
f1 = MyForm()
f2 = MyForm2()
f3 = MyForm()
alert(f1)
alert(f2)
alert(f3)
where f1
and f3
are two distinct instances of MyForm
.
Thank you so much. Will try these out