Python How to share info between events

  • Thread starter Thread starter cpscdave
  • Start date Start date
  • Tags Tags
    Events
AI Thread Summary
The discussion centers on the best practices for sharing information between mouse events in Python, specifically using wxPython. The primary focus is on capturing and comparing the mouse coordinates during EVT_LEFT_DOWN and EVT_LEFT_UP events. One participant mentions using a dictionary to store event information, while others suggest creating a dedicated class for better structure and clarity. A recommendation is made to implement a mouse class that handles events and maintains state, allowing for a more organized approach to event management. The conversation also touches on the importance of deciding where to handle mouse events based on the overall UI design, with considerations for whether to track events globally or locally within specific widgets. The use of an EventDispatcher is highlighted as a solution to overcome certain challenges in managing events effectively. Overall, the thread emphasizes the need for a balance between simplicity and structure when handling event-driven programming in Python.
cpscdave
Messages
402
Reaction score
120
What is the "proper" way in python to share information between events?

I'm mostly just playing around atm.
I'd like to compare the most position between a EVT_LEFT_DOWN and EVT_LEFT_UP events
I can use the class to store the information, but that seems a bit sloppy. Is there a better way??
Thanks!
 
Technology news on Phys.org
cpscdave said:
I'd like to compare the most position between a EVT_LEFT_DOWN and EVT_LEFT_UP events
Can you clarify this? It's not clear to me what you're saying.
 
When I'm expecting a chain of subsequent events, for example. Left mouse button down and then left mouse button (click and then release). I'd like to share information between the events.
In this specific case I pull out the x,y coordinate of where the mouse pointer is when the click happens and would like to compare it to where the release happens.

I'm wondering what the best method for storing that information.
What I'm doing right now is I've created a dictionary to dump that data. But I'm not sure if this is the best method to accomplish this.

Here is what I have so far. WHen you click it will put a rectangle on the screen. If you click that rectangle again it will delete it unless you "drag" it to a different location.
So I'm using the self.eventInfo dictionary to store the relevant information between the 2 event handlers.

Python:
import wx

class circle():
    def __init__(self, posX, posY, radius):
        self.posX = posX
        self.posY = posY
        self.radius = radius
class Shapes(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(350, 300))

        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_LEFT_DOWN, self.leftClickDown)
        self.Bind(wx.EVT_LEFT_UP,self.leftClickUp)
      
        self.eventInfo = {}
        self.eventInfo['leftClickDown'] = False
        self.cir = {}
        self.count = 0

        self.count+= 1
      
        self.Centre()
        self.Show(True)

      
    def leftClickUp(self,event):
        if( self.eventInfo['leftClickDown'] == False):
            return
        x, y = event.GetPosition()
        if(x == self.eventInfo['xPos'] and y== self.eventInfo['yPos']):
            del self.cir[self.eventInfo['key']]
        else:
            self.cir[self.eventInfo['key']].posX= x
            self.cir[self.eventInfo['key']].posY = y
        self.Refresh()
      
    def leftClickDown(self, event):
        self.eventInfo ={}
        self.eventInfo['leftClickDown'] = False
        x, y = event.GetPosition()
    
        print "Pos: " + str(x) + ", " + str(y)
        for key in self.cir:
            theCir = self.cir[key]
            print "\t" + str(theCir.posX) + " " + str(theCir.posY)
            if(x >= theCir.posX and x <= theCir.posX + 60 and
               y >= theCir.posY and y <= theCir.posY+ 60):
                self.eventInfo['leftClickDown'] = True
                self.eventInfo['key'] = key
                self.eventInfo['xPos'] = x
                self.eventInfo['yPos'] = y
                return
      
        self.cir[self.count] = circle(x-30, y-30, 60)
        self.flaggedKey = False
        self.count += 1
        self.Refresh()
      
    def OnPaint(self, event):
        dc = wx.PaintDC(self)

        for key in self.cir:
            theCir = self.cir[key]
            dc.DrawRectangle(theCir.posX, theCir.posY, theCir.radius, theCir.radius)app = wx.App()
Shapes(None, -1, 'Shapes')
app.MainLoop()

*EDIT* originally I was using circles instead of rectangles. Hence some of the nameing :)
 
The way you're doing it is the way I'd do it. I suspect a purist might prefer you to create a class that has the wx.Frame as a member and store your eventInfo in that class too "alongside" the Frame rather than "inside". Also, I might define a new class rather than use a dict, but that's just my style.
 
  • Like
Likes cpscdave
Perfect thanks!
 
That's exactly how to do it. Like Ibix said, you might benefit from having a separate structure for it, but it's not necessary considering the size of your class.

I wrote software for VOIP, and we often had to link multiple events together: when I get an END, you have to know things like if the INVITE that started the call had SDP, the capabilities of the phone... I stored all of that information in a structure.
 
  • Like
Likes cpscdave
This is just mucking around for the moment, but parts and pieces will get used in what I'm ultimately working on.
Want to try and avoid having to go back and rewriting big chunks cause I've programmed myself into a corner, and this would be my first real attempt at an event driven program :)
 
Oh, in that case, let me make a recommendation. Don't listen to the mouse events themselves, create a mouse class that does all that. Then "subscribe" to the mouse, and whenever the mouse gets an event, it dispatches a event object to all of it's subscribers. This class can include things like information about previous events, if you want to know the previous state of the mouse, it makes a lot more sense to ask a mouse class than to store it in a window.
 
I'll have to look into that.
I'm still wrapping my head around how to layout the program in general.
The good thing is this will be an internal testing tool only so if there are some less than optimal coding, it won't matter quite as much :)
 
  • #10
I think it can make sense to track mouse events in a window, although it depends on your overall UI design. If you have a lot of different widgets in your interface, most non-custom, and you don't want clicks outside your custom widget to affect the history of clicks in that window then it makes sense to record only the events that happen "inside" that widget.

On the other hand, you might want a mouse click event outside a widget to "reset" the recorded events inside a window. In that case you definitely want to catch mouse events at the earliest level you can and let your various widgets decide if they want to handle them, ignore them, or reset their history (or whatever).

It depends what you're trying to do, I think.
 
  • #11
What I need to track for the mouse is pretty straight forward. Right now I'm thinking I can get away with tracking it via events. That may change however :)

I did whip together an EventDispatcher and it fixed 2 hurdles I was having actually :)
 
  • #12
cpscdave said:
I did whip together an EventDispatcher and it fixed 2 hurdles I was having actually :)
Nice, I would make an EventListener class as well, and inherit from it for anything you want to have events. These are usually two of the first classes I write when starting a new project in any language.
 

Similar threads

Back
Top