Detect the mouse event on a moving frame

This is what I am trying to do: create a frame which is moving on the
screen, and if the user click on it before if finally stops moving,
the frame closes. The program is as follows. However, it seems that
the mouse click event is ignored until the two "for" loop ends. Any
ideas? Thanks.

···

--------------

import wx
import time

class MovingFrame(wx.Frame):
    def __init__(self):
        self.delay = 1 # Or 0.5 for faster motion
        divide = 4
        screenWidth, screenHeight = wx.DisplaySize()
        self.width, self.height = screenWidth/divide, screenHeight/
divide
        wx.Frame.__init__(self, None, style = wx.STAY_ON_TOP,
                          size=(self.width, self.height))
        self.Bind(wx.EVT_LEFT_UP, self.OnExit)
        self.Moving(divide)

    def OnExit(self, evt):
        self.Close(force=True)

    def Moving(self, divide):
        self.Show()
        for y in range(divide):
            posy = self.height*y
            for x in range(divide):
                posx = self.width*x
                self.Move(wx.Point(posx, posy))
                time.sleep(self.delay)

if __name__ == "__main__":
    app = wx.App()
    frame = MovingFrame()
    app.MainLoop()

--------------------

The wx main loop can't handle new events while you block it with your long running Moving method.

Try it like this:

import wx

class MovingFrame(wx.Frame):
     def __init__(self):
         self.delay = 1 # Or 0.5 for faster motion
         divide = 4
         screenWidth, screenHeight = wx.DisplaySize()
         self.width, self.height = screenWidth/divide, screenHeight/divide
         wx.Frame.__init__(self, None, style = wx.STAY_ON_TOP,
                           size=(self.width, self.height))
         self.Bind(wx.EVT_LEFT_UP, self.OnExit)
         self.Show()
         wx.CallAfter(self.Moving, self.MovingPoints(divide))

     def OnExit(self, evt):
         self.Close(force=True)

     def MovingPoints(self, divide):
         for y in range(divide):
             posy = self.height*y
             for x in range(divide):
                 posx = self.width*x
                 yield wx.Point(posx, posy)

     def Moving(self, points):
         try:
             self.Move(points.next())
             wx.CallLater(1000*self.delay, self.Moving, points)
         except StopIteration:
             pass

if __name__ == "__main__":
     app = wx.App()
     frame = MovingFrame()
     app.MainLoop()

···

On Mon, 02 May 2011 12:44:11 +0200, yltang <yltang0502@gmail.com> wrote:

This is what I am trying to do: create a frame which is moving on the
screen, and if the user click on it before if finally stops moving,
the frame closes. The program is as follows. However, it seems that
the mouse click event is ignored until the two "for" loop ends. Any
ideas? Thanks.

--------------

import wx
import time

class MovingFrame(wx.Frame):
    def __init__(self):
        self.delay = 1 # Or 0.5 for faster motion
        divide = 4
        screenWidth, screenHeight = wx.DisplaySize()
        self.width, self.height = screenWidth/divide, screenHeight/
divide
        wx.Frame.__init__(self, None, style = wx.STAY_ON_TOP,
                          size=(self.width, self.height))
        self.Bind(wx.EVT_LEFT_UP, self.OnExit)
        self.Moving(divide)

    def OnExit(self, evt):
        self.Close(force=True)

    def Moving(self, divide):
        self.Show()
        for y in range(divide):
            posy = self.height*y
            for x in range(divide):
                posx = self.width*x
                self.Move(wx.Point(posx, posy))
                time.sleep(self.delay)

if __name__ == "__main__":
    app = wx.App()
    frame = MovingFrame()
    app.MainLoop()

--------------------

That's exactly what I needed. Thanks a lot, Toni.

···

On 5月2日, 下午7時05分, Toni Ruža <gmr....@gmail.com> wrote:

The wx main loop can't handle new events while you block it with your long running Moving method.

Try it like this:

import wx

class MovingFrame(wx.Frame):
def __init__(self):
self.delay = 1 # Or 0.5 for faster motion
divide = 4
screenWidth, screenHeight = wx.DisplaySize()
self.width, self.height = screenWidth/divide, screenHeight/divide
wx.Frame.__init__(self, None, style = wx.STAY_ON_TOP,
size=(self.width, self.height))
self.Bind(wx.EVT_LEFT_UP, self.OnExit)
self.Show()
wx.CallAfter(self.Moving, self.MovingPoints(divide))

 def OnExit\(self, evt\):
     self\.Close\(force=True\)

 def MovingPoints\(self, divide\):
     for y in range\(divide\):
         posy = self\.height\*y
         for x in range\(divide\):
             posx = self\.width\*x
             yield wx\.Point\(posx, posy\)

 def Moving\(self, points\):
     try:
         self\.Move\(points\.next\(\)\)
         wx\.CallLater\(1000\*self\.delay, self\.Moving, points\)
     except StopIteration:
         pass

if __name__ == "__main__":
app = wx.App()
frame = MovingFrame()
app.MainLoop()

It’s best not to misuse the .CallAfter() function. Explicitly initializing and then calling a generator demystifies the generator’s usage.

Ray Pasco
pascor(at)verizon(dot)net

FramePositionGenerator.py (2.34 KB)

Thanks for your code, Ray. I think I need to spend tome time studying
your program for better understanding :wink:

···

On 5月3日, 上午5時51分, Ray Pasco <pascor22...@gmail.com> wrote:

It's best not to misuse the .CallAfter() function. Explicitly initializing
and then calling a generator demystifies the generator's usage.

Ray Pasco
pascor(at)verizon(dot)net

FramePositionGenerator.py
2K檢視下載