Tkinter: Strange behavior using place() and changing cursors

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mudcat

    #1

    Tkinter: Strange behavior using place() and changing cursors

    I was trying to design a widget that I could drag and drop anywhere in
    a frame and then resize by pulling at the edges with the mouse. I have
    fiddled with several different approaches and came across this behavior
    when using the combination of place() and configure(curso r = ...) This
    problem doesn't occur if you remove either one of these elements.

    It's a very basic design of a button wrapped in a sizer frame and is
    supposed to work like any window that can be resized. The mouse will
    change into a resize cursor when it hits the sizer frame (button's
    edge).

    However when the cursor hits the right edge it gets in some kind of
    loop where it keeps entering and leaving the frame. You can also cause
    this to happen by entering the widget from the bottom and slowly moving
    down. However it doesn't happen if you enter from the left or the top.

    Here's the code, boiled down to the basic components that seem to
    affect it in some way. Is there something I'm supposed to do in order
    to prevent this from happening?

    Thanks,
    Marc

    from Tkinter import *

    class Gui:
    def __init__(self, master):
    master.geometry ("200x100")
    btn = Widget(master)

    class Widget:
    def __init__(self, master):
    self.master = master
    self.buildFrame ()
    self.buildWidge t()

    def buildFrame(self ):
    self.f = Frame(self.mast er, height=32, width=32, relief=RIDGE,
    borderwidth=2)
    self.f.place(re lx=.5,rely=.5)
    self.f.bind( '<Enter>', self.enterFrame )
    self.f.bind( '<Leave>', self.leaveFrame )

    def buildWidget(sel f):
    self.b = Button(self.f, text="Sure!")
    self.b.pack(fil l=BOTH, expand=1)

    def enterFrame(self , event):
    self.f.configur e(cursor = 'sb_h_double_ar row')

    def leaveFrame(self , event):
    self.f.configur e(cursor = '' )

    root = Tk()
    ent = Gui(root)
    root.mainloop()

  • Wojciech Mu³a

    #2
    Re: Tkinter: Strange behavior using place() and changing cursors

    Mudcat wrote:
    [...]
    You have to set cursor once, Tk change it automatically:
    def buildFrame(self ):
    self.f = Frame(self.mast er, height=32, width=32, relief=RIDGE,
    borderwidth=2)
    self.f.place(re lx=.5,rely=.5)
    #self.f.bind( '<Enter>', self.enterFrame )
    #self.f.bind( '<Leave>', self.leaveFrame )
    self.f.configur e(cursor = 'sb_h_double_ar row')

    Comment

    • Mudcat

      #3
      Re: Tkinter: Strange behavior using place() and changing cursors


      Wojciech Mula wrote:
      Mudcat wrote:
      [...]
      >
      You have to set cursor once, Tk change it automatically:
      >
      def buildFrame(self ):
      self.f = Frame(self.mast er, height=32, width=32, relief=RIDGE,
      borderwidth=2)
      self.f.place(re lx=.5,rely=.5)
      #self.f.bind( '<Enter>', self.enterFrame )
      #self.f.bind( '<Leave>', self.leaveFrame )
      self.f.configur e(cursor = 'sb_h_double_ar row')

      The problem is I need the ability to change it dynamically. I don't
      want the cursor to be the double_arrow the whole time the mouse hovers
      inside that frame. It's supposed to be a resize arrow when the mouse is
      on the frame border, and regular cursor once it passes to the inner
      part of the frame.

      Unless there is a better way to do this, I have written code to
      determine if the mouse is on the edge or not. There doesn't seem to be
      a 'mouseover' type event to determine if the mouse is currently on the
      frame border itself. As a result, I calculate the position of the mouse
      and set the cursor appropriately.

      I have also determined that this is not a problem if the button is not
      packed inside the frame. So somehow the interaction of the internal
      button is causing this problem.

      Comment

      • Wojciech Mu³a

        #4
        Re: Tkinter: Strange behavior using place() and changing cursors

        Mudcat wrote:
        I have also determined that this is not a problem if the button is not
        packed inside the frame. So somehow the interaction of the internal
        button is causing this problem.
        Problem is really strange, and seems to be a Tk issue, not Tkinter.
        I've observed that if method configure is called and **any** parameter
        of frame is changed, then frame "forgets" all its children, gets natural
        size and then pack children again! This just(?) causes flickering, and
        do not depend on geometry manager --- all place, pack and grid work in
        this way. But only place causes the problem --- I guess it do not block
        events, or generate some events.

        Workaround:

        class Widget:
        def __init__(self, master):
        self.master = master
        self.buildFrame ()
        self.buildWidge t()
        self.x = 0
        self.y = 0

        # [snip]

        def enterFrame(self , event):
        if self.x != event.x or self.y != event.y:
        self.f.configur e(cursor = 'sb_h_double_ar row')
        self.x, self.y = event.x, event.y

        def leaveFrame(self , event):
        if self.x != event.x or self.y != event.y:
        self.f.configur e(cursor = '')
        self.x, self.y = event.x, event.y

        w.

        Comment

        • John McMonagle

          #5
          Re: Tkinter: Strange behavior using place() and changing cursors

          Mudcat wrote:
          Is there something I'm supposed to do in order
          to prevent this from happening?
          Yes. Instead of configuring the cursor on the frame, do it on the master:

          self.master.con figure(cursor=' sb_h_double_arr ow')




          --
          This message has been scanned for viruses and
          dangerous content by MailScanner, and is
          believed to be clean.

          Comment

          • Eric Brunel

            #6
            Re: Tkinter: Strange behavior using place() and changing cursors

            On Tue, 14 Nov 2006 17:45:52 +0100, Mudcat <mnations@gmail .comwrote:
            The problem is I need the ability to change it dynamically. I don't
            want the cursor to be the double_arrow the whole time the mouse hovers
            inside that frame. It's supposed to be a resize arrow when the mouse is
            on the frame border, and regular cursor once it passes to the inner
            part of the frame.
            Why don't you create a Frame for the inside with no border, and another
            Frame for the border? This way, you can have a cursor setting for each of
            them, i.e one for the inside and one for the border.

            HTH
            --
            python -c "print ''.join([chr(154 - ord(c)) for c in
            'U(17zX(%,5.zmz 5(17l8(%,5.Z*(9 3-965$l7+-'])"

            Comment

            Working...