tags:

views:

75

answers:

4

How can I trigger and listen for events in python ?

I need a practical example..

thanks

Update

#add Isosurface button
def addIso():
    #trigger event

self.addButton = tk.Button(self.leftFrame, text="Add", command=addIso) #.grid(column=3, row=1)
self.addButton.pack(in_=self.leftFrame, side="right", pady=2)
A: 

There's a bind function for TKinter objects that takes two parameters: the first is a string representing the name of the event you want to listen for (probably "" in this case), and the second is a method which takes the triggering event as a parameter.

Example:

def addButton_click(event):
    print 'button clicked'
self.addButton.bind("<Button-1>", addButton_click)

I believe this will still work even if used from another class:

class X:
    def addButton_click(self, event):
        print 'button clicked'
...
inst = X()
self.addButton.bind("<Button-1>", inst.addButton_click)
@user470379 so you need to have an instance (inst) of the class (X) having the function you want to call (addButton_click) in the button class. Then I actually don't need bind, because I can just directly invoke such function right ? The reason I was asking for an event is that I don't want relationships in between the 2 classes.
Patrick
I have not experience with python, I need something similar to what you have in Actionscript for example (addEventListener, triggerEvent methods)
Patrick
It depends on what type of function is in the other class. If it's an instance method, then yes, you need an instance. If it's a class method or static method, then you can just use the class itself without an instance (in this case it would be X.addButton_click). I'm not sure what you're wanting as far as relationships -- it sounds to me like you're trying to call functions in another class without using that other class.
A: 

Something like this:

#add Isosurface button
def addIso(event):
    #trigger event

self.addButton = tk.Button(self.leftFrame, text="Add") #.grid(column=3, row=1)
self.addButton.pack(in_=self.leftFrame, side="right", pady=2)
self.addButton.bind("<Button-1>", addIso)

From: http://www.bembry.org/technology/python/notes/tkinter_3.php

kanaka
@kanaka Thanks, what if the function addIso is in another class ?
Patrick
You'll probably need an intermediate function that calls the instance method, otherwise the event parameter will be passed as self (the instance object). I.e. addIso in the example would call myinst.addIso(event).
kanaka
Or you could use an anonymous function: bind(..., lambda e: myinst.addIso(e))
kanaka
@kanaka So, the only way is to instantiate the class (myinst) into my class ? The reason of my question is that I don't want relationships between the 2 classes..
Patrick
I may not understand your question then. By nature of binding the event in one class to the method of another class instance you are creating a relationship. "myinst" is just my name for a particular instance of the class you are wanting to call the method of.
kanaka
Bind is typically not used for buttons, as it already has a set of bindings that let it work. All you need to do is configure the command option of the button.
Bryan Oakley
A: 

If you are using IronPython with Windows Presentation Foundation (WPF), you can find pyevent.py in the Ironpython\Tutorial directory. This lets you write stuff like:

import clr
clr.AddReferenceByPartialName("PresentationFramework")
import System
import pyevent

class myclass(object):
    def __init__(self):
        self._PropertyChanged, self._OnPropertyChanged = pyevent.make_event()
        self.initialize()

    def add_PropertyChanged(self, handler):
        self._PropertyChanged += handler

    def remove_PropertyChanged(self, handler):
        self._PropertyChanged -= handler

    def raiseAPropertyChangedEvent(self, name):
        self._OnPropertyChanged(self, System.ComponentModel.PropertyChangedEventArgs(name))
Aphex
@Aphex I'm not using IronPython.. just Python preinstalled on mac OSX
Patrick
A: 

Based on your comments to some of the existing answers, I think what you want is something like the pubsub module. In the context of Tkinter, events are single purpose -- one event fires on one widget, and some handler handles the event (though there could be multiple handlers involved).

What it sounds like you want is more of a broadcast model -- your widget says "hey, the user did something" and any other module can register interest and get notifications without knowing specifically what widget or low level event caused that to happen.

I use this in an app that supports plugins. Plugins can say something like "call my 'open' method when the user opens a new file". They don't care how the user does it (ie: whether it was from the File menu, or a toolbar icon or a shortcut), only that it happened.

In this case, you would configure your button to call a specific method, typically in the same module that creates the button. That method would then use the pubsub module to publish some generic sort of event that other modules listen for and respond to.

Bryan Oakley