how to pass globals across modules (wxPython)

M

Martin Drautzburg

My wxPython program starts execution in mainFrame.py like this
[...]
class MainApp(wxApp):
def OnInit(self):
self.mainFrame = MainFrame(None)
self.mainFrame.Show()
self.SetTopWindow(self.mainFrame)
return True


def main():
global application
application=MainApp(0)
application.MainLoop()


if __name__ == '__main__':
main()


I need to access the "application" object from other modules, actually
the windows and frames that live therein and I don't know how to do
this.

I tried using "global", but that does not seem to help. In the other
module I run an "import mainFrame" and that seems to reset the global
variables.

Am I missing something obvious?
 
F

Fredrik Lundh

Martin said:
My wxPython program starts execution in mainFrame.py like this
[...]
class MainApp(wxApp):
def OnInit(self):
self.mainFrame = MainFrame(None)
self.mainFrame.Show()
self.SetTopWindow(self.mainFrame)
return True


def main():
global application
application=MainApp(0)
application.MainLoop()


if __name__ == '__main__':
main()


I need to access the "application" object from other modules, actually
the windows and frames that live therein and I don't know how to do
this.

this might help:

http://www.python.org/doc/faq/programming.html#how-do-i-share-global-variables-across-modules
I tried using "global", but that does not seem to help. In the other
module I run an "import mainFrame" and that seems to reset the global
variables.

"global" is used in a local scope to tell Python that something isn't a
local variable; see

http://www.python.org/doc/faq/programming.html#how-do-you-set-a-global-variable-in-a-function
http://www.python.org/doc/faq/progr...ules-for-local-and-global-variables-in-python

and

http://docs.python.org/ref/naming.html

for details.

</F>
 
P

Peter Hansen

Martin said:
My wxPython program starts execution in mainFrame.py like this
def main():
global application
application=MainApp(0)
application.MainLoop()

I need to access the "application" object from other modules, actually
the windows and frames that live therein and I don't know how to do
this.

I tried using "global", but that does not seem to help. In the other
module I run an "import mainFrame" and that seems to reset the global
variables.

Am I missing something obvious?

Not exactly obvious, perhaps, but well-defined. When you run
a Python script, the first script executed (the one specified
on the command line) is given the name __main__ in the list
of loaded modules (sys.modules, specifically). If you do an
"import mainFrame", you are actually loading a second copy
of the module into memory, under a different name.

The solution to your specific problem, without changing any
of the structure of your program, is to do "import __main__"
instead, but that's ultimately not likely the best solution.

One slightly better solution would be to create a special
empty module, just for holding "application globals" like
this, say "globals.py". Then you can import that in your
main script, and do "globals.application = MainApp(0)",
then import the same name elsewhere and work with it as you
are trying to.

An even better approach might be to find a way to avoid
having to access the main window through a global, but
I'll have to leave this up to you, as it may depend on
your program structure.

-Peter
 
L

Larry Bates

I also struggled with this until I looked into many
of the wxWindows examples. They all tend to pass in
the parent to each subsequent layer of classes so that
they can easily refer backwards in the hierarchy.

Example

In your code you will find that inside of SetTopWindow
you have parent as the first argument. You can refer
to parent.someattribute or parent.somemethod to refer
back to "application", which is instance of MainApp.
Just do something similar in MainFrame class.

Changing MainFrame class a little and passing in
self as the first argument will give you the same
ability inside of MainFrame instance. Something like:

class MainFrame(wxFrame):
def __init__(self, parentclass, parentframe):
self.parentclass=parentclass
wxFrame.__init__(self, parentframe, -1, "Frame Description")
.
.
.

Then in Main App pass self as first argument (parentclass),
then you can refer back to MainApp instance as
self.parentclass. If you go several levels down you
get self.parentclass.parentclass.parentclass.attribute:

class MainApp(wxApp):
def OnInit(self):
self.mainFrame = MainFrame(self, None)
self.mainFrame.Show()
self.SetTopWindow(self.mainFrame)
return True

This might not be the "best" way, but seems to work and models
what wxWindows appears to do internally.

Larry Bates
Syscon, Inc.
 
H

Hans Nowak

Martin said:
My wxPython program starts execution in mainFrame.py like this
[...]
class MainApp(wxApp):
def OnInit(self):
self.mainFrame = MainFrame(None)
self.mainFrame.Show()
self.SetTopWindow(self.mainFrame)
return True


def main():
global application
application=MainApp(0)
application.MainLoop()


if __name__ == '__main__':
main()


I need to access the "application" object from other modules, actually
the windows and frames that live therein and I don't know how to do
this.

If you just need to access the running application from other wxPython
objects, then wx.GetApp() is your friend.
 
J

Jorge Luiz Godoy Filho

Peter said:
An even better approach might be to find a way to avoid
having to access the main window through a global, but
I'll have to leave this up to you, as it may depend on
your program structure.

This might be a problem also to share a database connection, where one needs
to pass the open and authenticated connection to several specialized
modules.

Maybe a module where you can access that should be a better option...

Be seeing you,
Godoy.
 
F

Fredrik Lundh

Jorge said:
This might be a problem also to share a database connection, where one needs
to pass the open and authenticated connection to several specialized
modules.

Maybe a module where you can access that should be a better option...

or a single "application context class" instance, which is passed to various
parts of the system as necessary.

making subsystems dependent on a module can hinder reuse; making them
dependent on (parts of) the interface of an application context object makes
them a lot easier to reuse.

</F>
 
J

Jorge Luiz Godoy Filho

Fredrik said:
or a single "application context class" instance, which is passed to
various parts of the system as necessary.

Wouldn't that cause a chicken & egg problem? How, then, would one pass such
an instance across modules?

I'm sorry for my ignorance, but I'm a lot more slow than usually today and I
might have missed your point :)


Be seeing you,
Godoy.
 
F

Fredrik Lundh

Jorge said:
Wouldn't that cause a chicken & egg problem? How, then, would one pass such
an instance across modules?

well, in my applications, subsystems usually consists of one or more classes, or at least
one or more functions. code that needs the global context usually gets the content either
as a constructor argument, or as an argument to individual methods/functions.

if you build a system by execfile'ing subcomponents (or importing them just to run their
code, rather than use what they define), using this approach is harder. but that's not a
very good way to build systems, so I'm not sure that matters...

</F>
 
J

Jorge Luiz Godoy Filho

Fredrik said:
well, in my applications, subsystems usually consists of one or more
classes, or at least
one or more functions. code that needs the global context usually gets
the content either as a constructor argument, or as an argument to
individual methods/functions.

I see. Differences in terminology. We use the same approach as you do.


Be seeing you,
Godoy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top