[Tutor] A range of numbers [fixes to livewires]

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Wed Dec 3 15:30:37 EST 2003



On Wed, 3 Dec 2003, Magnus Lycka wrote:

> > Ya, that's true.... but even if i change it something like this:
> > >>def func():
> > >>         begin_graphics()
> > >>         box(200,200,300,300)
> > >>         begin_mouse()
> > >>         while 1:
> > >>
> > >>                 try:
> > >>                         x,y = mouse_position()
> > >>                 except:
> > >>                         x,y = 0,0
> > >>                 if 200 <= x <= 300 and 200 <= y <= 300 and mouse_buttons()['left'] == 1:
> > >>                         break
> > >>         end_mouse()
> > >>         box(300,200,500,500)
> >
> > It sill won't work. I've also tried putting time.sleep(0.05) before
> > the while loop ends , but it ....still freezes.
>
> Danny Yoo already explained why that won't work.


Hi Magnus,


I was wrong though.  *sigh* I took a closer look at the 'beginners'
module, and it should continue to update the mouse_position(), because
Livewires registers a callback for it.



>From looking at the code, I see that mouse_position() is defined to return
None if the mouse isn't on screen.  Since that's not convenient for us, we
can write a small wrapper around it to make things nicer:

###
def my_mouse_position():
    """A thin wrapper around mouse_position() that always returns a
    2-tuple.  If the mouse isn't on screen, returns (-1, -1)."""
    pos = mouse_position()
    if pos == None:
        return (-1, -1)
    return pos
###


So we don't need to use any exception handling.




The inner loop:

> > >>         while 1:
> > >>
> > >>                 try:
> > >>                         x,y = mouse_position()
> > >>                 except:
> > >>                         x,y = 0,0
> > >>                 if 200 <= x <= 300 and 200 <= y <= 300 and mouse_buttons()['left'] == 1:
> > >>                         break


is freezing because it is not giving the system a chance to update the
mouse state.  So we do need to call mouse_wait().



However, it looks like there may be some severe bugs in Livewires's
handling of the mouse!  There's definitely several typos where the
Livewires code is calling the wrong Tkinter methods for fiddling with the
event loop.

I've made the following changes to Livewires's 'beginners.py' file to
correct some bugs.  For those that are familiar with 'diff', here are the
changes I've made:


###
[dyoo at tesuque tmp2]$ diff LiveWires-2.0/livewires/beginners.py
../LiveWires-2.0/
livewires/beginners.py
694c694
<         while _mouse_b == 0: _root_window.dooneevent()
---
>         while _mouse_b == 0: _root_window.tk.dooneevent()
696c696
<         while _mouse_b != 0: _root_window.dooneevent()
---
>         while _mouse_b != 0: _root_window.tk.dooneevent()
699c699
<         while _mouse_b == b: _root_window.dooneevent()
---
>         while _mouse_b == b: _root_window.tk.dooneevent()
704c704
<             _root_window.dooneevent()
---
>             _root_window.tk.dooneevent()
707c707
<         while x == _mouse_x and y == _mouse_y: _root_window.dooneevent()
---
>         while x == _mouse_x and y == _mouse_y:
_root_window.tk.dooneevent()
711c711
<             _root_window.dooneevent()
---
>             _root_window.tk.dooneevent()
725c725,728
<     _mouse_x, _mouse_y = None, None
---
>     ## (dyoo) commented out: this appears to be causing some ugly
problems
> ##     _mouse_x, _mouse_y = None, None
>
>
###



I've packaged up these corrections into the file:

    http://hkn.eecs.berkeley.edu/~dyoo/python/LiveWires-2.01.tar.gz


I'm putting this up temporarily so that Leung can try it out.  With this,
the program:


###
from livewires import *

def my_mouse_position():
    """A thin wrapper around mouse_position() that always returns a
    2-tuple.  If the mouse isn't on screen, returns (-1, -1)."""
    pos = mouse_position()
    if pos == None:
        return (-1, -1)
    return pos


def func():
    begin_graphics()
    box(200,200,300,300)
    begin_mouse()
    while 1:
        mouse_wait('any')
        x, y = my_mouse_position()
        print "(x, y) = ", (x,y)
        if (200 <= x <= 300 and 200 <= y <= 300
                and mouse_buttons()['left'] == 1):
            break
    end_mouse()
    box(300,200,500,500)
###

appears to work ok.  There's still some wacky situation going on with the
'<Leave>' event that I haven't figured out yet, so I've commented it out
of the Livewires code.


Anyway, when I have the time, I'll send an email over to the Livewires
folks later to see if we can fold these corrections into their code.


Whew.  Ok, back to work for me.  *grin* Talk to you later!




More information about the Tutor mailing list