This is certainly simple, but I have no examples in my prior code[1] and
cannot find an example on the Web, perhaps because I'm not using the proper
search string.
In class MainFrame(wx.Frame) is the menu. For a menu item I want to bind a
class, ChangePasswordDialog(wx.Dialog) to that menu item:
wxPython tells me that ChangePasswordDialog() is not globally defined, but
it's not in the MainFrame class so the 'self' prefix is inappropriate. A
pointer to the proper syntax will be quite helpful.
TIA,
Rich
[1] In prior code the methods were in the same MainFrame class as the menu.
Rich,
This is really a python question rather than a wxPython one,
whenever you refer to a function or any other item it can be:
···
On 16/07/14 22:44, Rich Shepard wrote:
This is certainly simple, but I have no examples in my prior
code[1] and
cannot find an example on the Web, perhaps because I'm not using
the proper
search string.
In class MainFrame(wx.Frame) is the menu. For a menu item I want
to bind a
class, ChangePasswordDialog(wx.Dialog) to that menu item:
self.Bind(wx.EVT_MENU, ChangePasswordDialog(), menuPasswd)
wxPython tells me that ChangePasswordDialog() is not globally
defined, but
it's not in the MainFrame class so the 'self' prefix is
inappropriate. A
pointer to the proper syntax will be quite helpful.
TIA,
Rich
[1] In prior code the methods were in the same MainFrame class as
the menu.
A global item in the same name space: just use
ItemName
An item imported from elsewhere with from somewhere import
ItemName is added as a global in the current scope so use the
same so you can use from maths import (sin,pi);x=sin(pi/3).
A member of the same class: use self.ItemName
A member of another class defined in the same scope or
imported from somewhere by the class name: use NameOfClassInstance .ItemName
i.e. if your class Parrot has a method IsDead you need to from
birds import Parrot;AmazonBlue=Parrot(…);if
AmazonBlue.IsDead():
A class method does not need an instance so you might be able
to use if from birds import Parrot;Parrot.IsDead():
Items that are global in a given import so can be used as
import birds:if birds.LaysEggs():
Basically if you have ChangePasswordDialog ** in the current
file** for your binding, (that name sounds like a window
rather than a function so I will assume that it is), you need a ** function** that takes an event as the input to bind. The usual is to
make that function be a member of the same class so you would use:
self.Bind(wx.EVT_MENU, self.On ChangePasswordDialog,
menuPasswd)
* Note no brackets as you are referring to the method not the
result of the method.*
and in your class have:
def OnChangePasswordDialog(self, evt):
# Create a ChangePasswordDialog, show it, process the result
Hope that helps - for better examples look at the demos in the
Docs & Demos package - they are brilliant examples of how to
do things.
Hi Gadget/Steve and Rich. Building on G/S's answer, I'd do it just a bit
differently, and to add in everything to possibly clarify it a bit more for
Rich:
def ShowChangePasswordDialog():
change_dlg = ChangePasswordDialog(...arguments...)
result = change_dlg.ShowModal()
# etc... do something with result, eventually destroy the dlg...or you
could do the style Werner
# suggested, which is using a context manager (the "with" style)
I just like to name the event handlers in terms of the event they are
handling (here, using that menu item), and I also prefer to have a separate
function, named as a verb, that does whatever stuff I want the event
handler to kick off, but just call that function from the event handler
function. This way, if I later want to get to the ChangePasswordDialog
from some other means, there is already a function that just does that,
plus I have a clearly named verb-phrased function name in the namespace
that I can find in the IDE's explorer, whereas if it were just the handler,
I wouldn't be sure what it did.
Che
···
On Thu, Jul 17, 2014 at 1:09 AM, Steve Barnes <gadgetsteve@live.co.uk> wrote:
On 16/07/14 22:44, Rich Shepard wrote:
This is certainly simple, but I have no examples in my prior code[1] and
cannot find an example on the Web, perhaps because I'm not using the
proper
search string.
In class MainFrame(wx.Frame) is the menu. For a menu item I want to bind
a
class, ChangePasswordDialog(wx.Dialog) to that menu item:
wxPython tells me that ChangePasswordDialog() is not globally defined, but
it's not in the MainFrame class so the 'self' prefix is inappropriate. A
pointer to the proper syntax will be quite helpful.
TIA,
Rich
[1] In prior code the methods were in the same MainFrame class as the
menu.
Rich,
This is really a python question rather than a wxPython one, whenever you
refer to a function or any other item it can be:
1. A *global* item in the same name space: just use ItemName
2. An item imported from elsewhere with from somewhere import ItemName
is added as a global in the current scope so use the same so you can use
from maths import (sin,pi);x=sin(pi/3).
3. A member of the same class: use self.ItemName
4. A member of another class defined in the same scope or imported
from somewhere by the class name: use NameOfClass*Instance*.ItemName
i.e. if your class Parrot has a method IsDead you need to from birds import
Parrot;AmazonBlue=Parrot(....);if AmazonBlue.IsDead():
5. A class method does not need an instance so you might be able to
use if from birds import Parrot;Parrot.IsDead():
6. Items that are global in a given import so can be used as import
birds:if birds.LaysEggs():
Basically if you have ChangePasswordDialog *in the current file* for your
binding, (that name sounds like a window rather than a function so I will
assume that it is), you need a *function *that takes an event as the
input to bind. The usual is to make that function be a member of the same
class so you would use:
self.Bind(wx.EVT_MENU, *self.On*ChangePasswordDialog, menuPasswd) # *Note
no brackets as you are referring to the method not the result of the
method.*
and in your class have:
def *On*ChangePasswordDialog(self, evt):
#* Create a ChangePasswordDialog, show it, process the result*
insert your code to continue the password changes.
What this does is create an instance of your ChangePasswordDialog class, then make it show as modal. By making it modal you prevent the user from doing anything else with your application until they finish resetting their password. The line if passwdDlg.ShowModal() == wx.ID_OK: also tells your program that the code within the statement should only be run IF the user clicks the “OK” / “Submit” button
···
On Wednesday, July 16, 2014 5:44:42 PM UTC-4, fuzzydoc wrote:
This is certainly simple, but I have no examples in my prior code[1] and
cannot find an example on the Web, perhaps because I’m not using the proper
search string.
In class MainFrame(wx.Frame) is the menu. For a menu item I want to bind a
class, ChangePasswordDialog(wx.Dialog) to that menu item:
def onChangePasswordDlg(self, event):
passwdDlg = ChangePasswordDialog()
if passwdDlg.ShowModal() == wx.ID_OK:
# insert your code to continue the password changes.
On Wednesday, July 16, 2014 10:09:40 PM UTC-7, Gadget Steve wrote:
Basically if you have ChangePasswordDialog ** in the current
file** for your binding, (that name sounds like a window
rather than a function so I will assume that it is), you need a ** function**that takes an event as the input to bind. The usual is to
make that function be a member of the same class
This is certainly simple, but I have no examples in my prior code[1] and
cannot find an example on the Web, perhaps because I'm not using the proper
search string.
In class MainFrame(wx.Frame) is the menu. For a menu item I want to bind a
class, ChangePasswordDialog(wx.Dialog) to that menu item:
I want to make sure you understand the key issue here. You can't bind a
class to an event. You can only bind a function. The function you
supply can create a new instance of the dialog and display it.
Also, just to be technical, you're not actually passing a class there.
You are creating a new object and passing that object.
···
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
You beat me to it. I realized that I hadn’t completely explained my example due to writing it while being distracted by other people asking me questions in person. Thank you for providing the details I forgot.
···
On Thursday, July 17, 2014 1:21:47 PM UTC-4, Tim Roberts wrote:
Rich Shepard wrote:
This is certainly simple, but I have no examples in my prior code[1] and
cannot find an example on the Web, perhaps because I’m not using the proper
search string.
In class MainFrame(wx.Frame) is the menu. For a menu item I want to bind a
class, ChangePasswordDialog(wx.Dialog) to that menu item:
There is a subtle difference between your example and his. You
had:
btn.Bind(wx.EVT_BUTTON, tc)
He had:
self.Bind(wx.EVT_MENU, ChangePasswordDialog(), menuPasswd)
In your case you are passing a class. A class is “callable”, like a
function. Calling a class is how we create an instance. So, when
the event mechanism goes to trigger the event, it ends up creating a
temporary object, calling the constructor, and then discarding it.
In the original example, he has those extra parens. What he was
passing was not a class, but an instance of the class. An instance
is not “callable” (unless you supply a magic method).
In any case, what he was doing is not what he wanted to do.
···
Nathan McCorkle wrote:
On Wednesday, July 16, 2014 10:09:40 PM UTC-7, Gadget Steve
wrote:
Basicall y if you have
ChangePasswordDialog in the current file for your binding, (that name sounds like a
window rather than a function so I will assume that it
is), you need a **
function** that takes an event
as the input to bind. The usual is to make that function be a member of
the same class
But does it /need/ to be? It doesn't seem like it, as this
I’d think it would be passing the init function of that class…
···
On Thursday, July 17, 2014 10:28:31 AM UTC-7, Tim Roberts wrote:
There is a subtle difference between your example and his. You
had:
btn.Bind(wx.EVT_BUTTON, tc)
He had:
self.Bind(wx.EVT_MENU, ChangePasswordDialog(), menuPasswd)
In your case you are passing a class. A class is "callable", like a
No the init function will be called before the bind and return a
temporary class instance, (which will then be bound to the event),
so will need to be, itself, callable with a single parameter for the
event - it is possible to construct such a class but I suspect
rarely worth it.
Gadget/Steve
···
On 17/07/14 19:41, Nathan McCorkle
wrote:
On Thursday, July 17, 2014 10:28:31 AM UTC-7, Tim Roberts wrote:
There is a subtle
difference between your example and his. You had:
btn.Bind(wx.EVT_BUTTON, tc)
He had:
self.Bind(wx.EVT_MENU, ChangePasswordDialog(),
menuPasswd)
In your case you are passing a class. A class is
“callable”, like a function.
I'd think it would be passing the init function of that
uhh, in the demo I posted of doing just this… the print in the init doesn’t show up until the event occurs.
···
On Thursday, July 17, 2014 11:55:19 AM UTC-7, Gadget Steve wrote:
On 17/07/14 19:41, Nathan McCorkle > wrote:
On Thursday, July 17, 2014 10:28:31 AM UTC-7, Tim Roberts wrote:
There is a subtle
difference between your example and his. You had:
btn.Bind(wx.EVT_BUTTON, tc)
He had:
self.Bind(wx.EVT_MENU, ChangePasswordDialog(),
menuPasswd)
In your case you are passing a class. A class is
“callable”, like a function.
I'd think it would be passing the init function of that
class…
–
No the init function will be called before the bind and return a
temporary class instance, (which will then be bound to the event),
so will need to be, itself, callable with a single parameter for the
event - it is possible to construct such a class but I suspect
rarely worth it.
Nope. In order to call the init function, there would have to
be an instance of the class (“self”), and there is no such object
here yet.
No, it is actually passing the class, which is itself an object. A
function is ALSO an object. In Python terms, both of those objects
happen to be “callables”, which means they have a “call” method
implemented. In the case of a class, the “call” method
allocates a new object, then calls the new and init methods.
···
Nathan McCorkle wrote:
On Thursday, July 17, 2014 10:28:31 AM UTC-7, Tim Roberts wrote:
There is a subtle
difference between your example and his. You had:
btn.Bind(wx.EVT_BUTTON, tc)
He had:
self.Bind(wx.EVT_MENU, ChangePasswordDialog(),
menuPasswd)
In your case you are passing a class. A class is
“callable”, like a function.
I'd think it would be passing the init function of that
I’m not sure how to interpret that, since as I said, I don’t see the print in the init function until I actually click the button. I don’t think a new class is being instantiated at event binding time… or we’re all missing some key info about Python objects/functions/classes.
···
On Thursday, July 17, 2014 12:19:34 PM UTC-7, Tim Roberts wrote:
Nathan McCorkle wrote:
On Thursday, July 17, 2014 10:28:31 AM UTC-7, Tim Roberts wrote:
There is a subtle
difference between your example and his. You had:
btn.Bind(wx.EVT_BUTTON, tc)
He had:
self.Bind(wx.EVT_MENU, ChangePasswordDialog(),
menuPasswd)
In your case you are passing a class. A class is
“callable”, like a function.
I'd think it would be passing the init function of that
class…
Nope. In order to call the __init__ function, there would have to
be an instance of the class (“self”), and there is no such object
here yet.
No, it is actually passing the class, which is itself an object. A
function is ALSO an object. In Python terms, both of those objects
happen to be “callables”, which means they have a “call” method
implemented. In the case of a class, the “call” method
allocates a new object, then calls the new and init methods.
No, what I said matches what you observe. You are passing the
“class object” – the object that is the class. That object gets
stored in the event machinery. When the event actually fires, the
code grabs that object and calls it, by invoking its call
method. For a class, the call method creates a new object (or
calls new to do that same task), then calls init.
Since the newly created object isn’t being stored anywhere, it will
then immediately get destroyed.
···
Nathan McCorkle wrote:
On Thursday, July 17, 2014 12:19:34 PM UTC-7, Tim Roberts wrote:
No, it is actually passing the class, which is itself an
object. A function is ALSO an object. In Python terms,
both of those objects happen to be “callables”, which means
they have a “call” method implemented. In the case of a
class, the “call” method allocates a new object, then
calls the new and init methods.
I'm not sure how to interpret that, since as I said, I
don’t see the print in the init function until I actually
click the button. I don’t think a new class is being
instantiated at event binding time… or we’re all missing
some key info about Python objects/functions/classes.
Ahh, ok, that makes sense… it’s the CLASS object, not an instantiation of that CLASS. In my demo, I replaced the class name in the Bind with className.call and get the same behavior! Cool!
I was actually going down a rat/rabbit-hole earlier-this/last week with overloading call and getattr to try a threaded object appear like a non-threaded object… I found a saner route to get around my problem though, but still glad to be ‘connecting the dots’.
···
On Thursday, July 17, 2014 1:12:58 PM UTC-7, Tim Roberts wrote:
No, what I said matches what you observe. You are passing the
“class object” – the object that is the class. That object gets
stored in the event machinery. When the event actually fires, the
code grabs that object and calls it, by invoking its call
method. For a class, the call method creates a new object (or
calls new to do that same task), then calls init.
No, what I said matches what you observe. You are passing the "class
object" -- the object that is the class.
are you sure -- in what he posted, he had parens after than class name --
which would get evaluated when the bind code was run, which would result in
the event being bound to an instance. And if that instance wasn't callable
would result in a event-time error:
which would indeed pass a class object to the event binder, and its
__init__ would get called at event time.
-CHB
···
On Thu, Jul 17, 2014 at 1:12 PM, Tim Roberts <timr@probo.com> wrote:
--
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception