views:

81

answers:

2

How would I vibrate a window in wxPython. I'd like some way of specifying how long to do it for and distance and stuff like that.

Is there a builtin function I'm not noticing or would I have to code it myself?
(I'm thinking of moving the window sideways a few times but I'd rather have a builtin function that might be faster.)

+4  A: 

I don't think there is any such function, but you can easily do it using win.SetPosition

e.g. click inside frame to vibrate

import wx

def vibrate(win, count=20, delay=50):
    if count == 0: return
    x, y = win.GetPositionTuple()
    dx = 2*count*(.5-count%2)
    win.SetPosition((x+dx,y))
    wx.CallLater(delay, vibrate, win, count-1, delay)

app = wx.PySimpleApp()
frame = wx.Frame(None, title="Vibrator")
frame.Show()
frame.Bind(wx.EVT_LEFT_DOWN, lambda e:wx.CallAfter(vibrate, frame))
app.SetTopWindow(frame)
app.MainLoop()
Anurag Uniyal
That's exactly what I was looking for. You can see in my answer what I was doing meanwhile. This doesn't seem to run for me though, but I'm pretty sure that's just me (I've got different IDE's that some feel like running some code, some don't). No error messages, so it's definitely my interpreters' problem.
vlad003
What version of wxPython are you using? -- AttributeError: 'module' object has no attribute 'CallLater'
remosu
@remosu, >>> wx.VERSION -> (2, 8, 10, 1, ''), i wonder what is your version?
Anurag Uniyal
@vlad003, mostly if something is not working, it is not interpreter's problem :), anyway your solution is almost there, but problem is that you are updating window pos in same event multiple time, so based on OS it may or may not work depending on if wx process events correctly, so best bet is to change position using wxPython events.
Anurag Uniyal
@remosu , in version 2.7.7.1 wx.FutureCall was renamed to wx.Callafter http://www.wxpython.org/recentchanges.php, so you must be having a old version
Anurag Uniyal
@Anurag, I'm still gonna say that it's an interpreter problem :P. If I run my answer's code using the python interpreter in the terminal, it doesn't run. I have a IDLE-like interpreter plugin for my text editor which does run the code correctly. Sometimes it's vice versa. I'll have to look into it. Anyways, thanks for your response. I have yet to fully understand it but I'll look at the docs for all the functions. Thanks
vlad003
@Anurag: thanks. wx.VERSION == (2, 6, 3, 2, '') yes I'm outdated
remosu
@Anurag: What OS are you running this on?
vlad003
@vlad003, I ran it on windows XP
Anurag Uniyal
Your code's working in both my interpreters. My code's running only in one. I guess it's an example of it not always working :PI'll be using yours as soon as I understand it all. This is the first thing I've done in GUI so I've got lots to learn.
vlad003
A: 

Until people answered my question, I was working on my own method of doing it. I've only started GUI programming so I don't know all the features of wx so I ended up using the time module. Anurag's method is probably better since it uses wx functions, but I'll post this here anyways as another way of doing it.
NOTE: This may not always work (I'm having trouble getting it to work with diff interpreters on same OS). So use Anurag's method.

import wx

def vibrate(windowName, distance=15, times=5, speed=0.05, direction='horizontal'):
    #Speed is the number of seconds between movements
    #If times is odd, it increments so that window ends up in same location
    import time
    if not times % 2 == 0:
        times += 1
    location = windowName.GetPositionTuple()
    if direction == 'horizontal':
        newLoc = (location[0] + distance, location[1])
    elif direction == 'vertical':
        newLoc = (location[0], location[1] + distance)
    for x in range(times):
        time.sleep(speed)
        windowName.Move(wx.Point(newLoc[0], newLoc[1]))
        time.sleep(speed)
        windowName.Move(wx.Point(location[0], location[1]))

app = wx.App()

frame = wx.Frame(None, -1, 'Vibrator')
frame.Show()

vibrate(frame)

app.MainLoop()
vlad003