What I’m trying to do:
I have created a layout with 6 pages that use the layout. At startup I show the main page (NOT based on the layout) and if a user selects a project the first page using the layout is shown. I pass the project_id into the properties parameters. On that page the project is loaded from the database. I now want to share that object on any page that is based on the layout.
What I’ve tried and what’s not working:
I have tried to add a field to the layout but that does not work since every form based on the layout has a different instance of the layout object.
My current solution is to store the id of the project being edited in a database and use a database query on every page to find the currently selected object but this adds overhead which I hope to reduce.
Code Sample:
# this is the code I use now (on every page that uses the layout)
# is the page called from the main page then the project_id is given in the properties dict
if 'project_id' in properties.keys():
project_id= properties['project_id']
anvil.server.call('set_active_project_id', anvil.users.get_user()['email'], project_id)
else:
project_id= anvil.server.call('get_active_project_id', anvil.users.get_user()['email'])
The layout form is defined as a class, in a Python file (source module), but that’s not the only thing that the Python module can define! It can define its own module-level constants and variables. Those persist for the lifetime of the class definition, so they are effectively of global lifetime. All instances of the class can easily access them, since they’re in the same module. Look up Python’s global keyword, for more details.
I am looking for a solution to the same problem. Prior to Layouts I would load each form in to a ‘holding’ form and ad variables in code such as ‘myvariable’. This could then be accessed from the currently active form using get_open_form().myvariable. This doesn’t work for a Layout.
I had a look at Python’s global but couldn’t find anything that seemed relevant.
The following code creates a global-lifetime variable, num_lives. Since it is scoped to the module, not any particular instance of a Form, there is only instance of the variable in the entire program. All of the module’s functions that wish to be able to write the variable can declare it as global. Those that merely wish to read it do not have to declare it.
from ._anvil_designer import Frame_OptionsForRunTemplate
# module-level global variables
num_lives: int = 1
class Frame_OptionsForRun(Frame_OptionsForRunTemplate):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
def reset(self):
global num_lives
num_lives = 1
Code in other modules can access it if need be:
import Frame_OptionsForRun
...
if Frame_OptionsForRun.num_lives > 1:
...
Thanks PC. That makes sense and is exactly what I (we?) needed.
Thank you again; again in the sense that this is not the first time you’ve got me out of hole. The community is fantastic.