Tkinter canvas drag/drop obstacle

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

    Tkinter canvas drag/drop obstacle

    Tkinter makes it very easy to drag jpeg images around on a
    canvas, but I would like to have a "target" change color when
    the cursor dragging an image passes over it. I seem to be
    blocked by the fact that the callbacks that might tell the
    target that the mouse has entered it (<Enter>, <Any-Enter>,
    even <Motion>) aren't called if the mouse's button is down.
    What am I missing? Have I failed to find the right Tkinter
    document? Is Tkinter the wrong tool for this job? Thanks.

    --
    To email me, substitute nowhere->spamcop, invalid->net.
  • Guilherme Polo

    #2
    Re: Tkinter canvas drag/drop obstacle

    On Fri, Jun 20, 2008 at 1:11 PM, Peter Pearson <ppearson@nowhe re.invalidwrote :
    Tkinter makes it very easy to drag jpeg images around on a
    canvas, but I would like to have a "target" change color when
    the cursor dragging an image passes over it. I seem to be
    blocked by the fact that the callbacks that might tell the
    target that the mouse has entered it (<Enter>, <Any-Enter>,
    even <Motion>) aren't called if the mouse's button is down.
    What am I missing? Have I failed to find the right Tkinter
    document? Is Tkinter the wrong tool for this job? Thanks.
    >
    I believe the only way to achieve this is binding <Motionto the
    entire canvas, then checking if the x, y coords are inside the
    "target".
    --
    To email me, substitute nowhere->spamcop, invalid->net.
    --

    >
    --
    -- Guilherme H. Polo Goncalves

    Comment

    • Matimus

      #3
      Re: Tkinter canvas drag/drop obstacle

      On Jun 20, 9:11 am, Peter Pearson <ppear...@nowhe re.invalidwrote :
      Tkinter makes it very easy to drag jpeg images around on a
      canvas, but I would like to have a "target" change color when
      the cursor dragging an image passes over it.  I seem to be
      blocked by the fact that the callbacks that might tell the
      target that the mouse has entered it (<Enter>, <Any-Enter>,
      even <Motion>) aren't called if the mouse's button is down.
      What am I missing?  Have I failed to find the right Tkinter
      document?  Is Tkinter the wrong tool for this job?  Thanks.
      >
      --
      To email me, substitute nowhere->spamcop, invalid->net.
      I have used a combination of <Motionand <B1-Motion>. You might also
      throw in a <Button-1event to keep track of whether or not the mouse
      button was down when it entered the widget or not.

      Depending on what you really want to do though, you might take
      advantage of the 'active' state:

      import Tkinter as tk

      can = tk.Canvas()
      can.pack(fill=t k.BOTH, expand=True)

      can.create_rect angle(
      10,10,100,100,
      fill="black",
      activewidth=5,
      activeoutline=" blue"
      )

      can.mainloop()

      The 'active*' options take effect when the mouse is on top of that
      item.

      If all you are _really_ interested in is a visual indicator, this
      should work for you. Note that there is also a disabled state. I only
      discovered this by looking at the options available and guessing.
      >>from pprint import pprint
      >>import Tkinter as tk
      >>can = tk.Canvas()
      >>can.pack(fill =tk.BOTH, expand=True)
      >>r = can.create_rect angle(10,10,100 ,100)
      >>pprint(can.it emconfig(r))
      {'activedash': ('activedash', '', '', '', ''),
      'activefill': ('activefill', '', '', '', ''),
      'activeoutline' : ('activeoutline ', '', '', '', ''),
      'activeoutlines tipple': ('activeoutline stipple', '', '', '', ''),
      'activestipple' : ('activestipple ', '', '', '', ''),
      'activewidth': ('activewidth', '', '', '0.0', '0.0'),
      'dash': ('dash', '', '', '', ''),
      'dashoffset': ('dashoffset', '', '', '0', '0'),
      'disableddash': ('disableddash' , '', '', '', ''),
      'disabledfill': ('disabledfill' , '', '', '', ''),
      'disabledoutlin e': ('disabledoutli ne', '', '', '', ''),
      'disabledoutlin estipple': ('disabledoutli nestipple', '', '', '', ''),
      'disabledstippl e': ('disabledstipp le', '', '', '', ''),
      'disabledwidth' : ('disabledwidth ', '', '', '0.0', '0'),
      'fill': ('fill', '', '', '', ''),
      'offset': ('offset', '', '', '0,0', '0,0'),
      'outline': ('outline', '', '', 'black', 'black'),
      'outlineoffset' : ('outlineoffset ', '', '', '0,0', '0,0'),
      'outlinestipple ': ('outlinestippl e', '', '', '', ''),
      'state': ('state', '', '', '', ''),
      'stipple': ('stipple', '', '', '', ''),
      'tags': ('tags', '', '', '', ''),
      'width': ('width', '', '', '1.0', '1.0')}

      The 'state' option can be set to 'normal', 'hidden' or 'disabled'. So
      if you want to make your canvas items look different when they are
      disabled, set the disabled* options and set 'state' to 'disabled'.

      Matt

      Comment

      • Matimus

        #4
        Re: Tkinter canvas drag/drop obstacle

        On Jun 20, 11:10 am, Matimus <mccre...@gmail .comwrote:
        On Jun 20, 9:11 am, Peter Pearson <ppear...@nowhe re.invalidwrote :
        >
        Tkinter makes it very easy to drag jpeg images around on a
        canvas, but I would like to have a "target" change color when
        the cursor dragging an image passes over it.  I seem to be
        blocked by the fact that the callbacks that might tell the
        target that the mouse has entered it (<Enter>, <Any-Enter>,
        even <Motion>) aren't called if the mouse's button is down.
        What am I missing?  Have I failed to find the right Tkinter
        document?  Is Tkinter the wrong tool for this job?  Thanks.
        >
        --
        To email me, substitute nowhere->spamcop, invalid->net.
        >
        I have used a combination of <Motionand <B1-Motion>. You might also
        throw in a <Button-1event to keep track of whether or not the mouse
        button was down when it entered the widget or not.
        >
        Depending on what you really want to do though, you might take
        advantage of the 'active' state:
        >
        import Tkinter as tk
        >
        can = tk.Canvas()
        can.pack(fill=t k.BOTH, expand=True)
        >
        can.create_rect angle(
                10,10,100,100,
                fill="black",
                activewidth=5,
                activeoutline=" blue"
                )
        >
        can.mainloop()
        >
        The 'active*' options take effect when the mouse is on top of that
        item.
        >
        If all you are _really_ interested in is a visual indicator, this
        should work for you. Note that there is also a disabled state. I only
        discovered this by looking at the options available and guessing.
        >
        >from pprint import pprint
        >import Tkinter as tk
        >can = tk.Canvas()
        >can.pack(fill= tk.BOTH, expand=True)
        >r = can.create_rect angle(10,10,100 ,100)
        >pprint(can.ite mconfig(r))
        >
        {'activedash': ('activedash', '', '', '', ''),
         'activefill': ('activefill', '', '', '', ''),
         'activeoutline' : ('activeoutline ', '', '', '', ''),
         'activeoutlines tipple': ('activeoutline stipple', '', '', '', ''),
         'activestipple' : ('activestipple ', '', '', '', ''),
         'activewidth': ('activewidth', '', '', '0.0', '0.0'),
         'dash': ('dash', '', '', '', ''),
         'dashoffset': ('dashoffset', '', '', '0', '0'),
         'disableddash': ('disableddash' , '', '', '', ''),
         'disabledfill': ('disabledfill' , '', '', '', ''),
         'disabledoutlin e': ('disabledoutli ne', '', '', '', ''),
         'disabledoutlin estipple': ('disabledoutli nestipple', '', '', '', ''),
         'disabledstippl e': ('disabledstipp le', '', '', '', ''),
         'disabledwidth' : ('disabledwidth ', '', '', '0.0', '0'),
         'fill': ('fill', '', '', '', ''),
         'offset': ('offset', '', '', '0,0', '0,0'),
         'outline': ('outline', '', '', 'black', 'black'),
         'outlineoffset' : ('outlineoffset ', '', '', '0,0', '0,0'),
         'outlinestipple ': ('outlinestippl e', '', '', '', ''),
         'state': ('state', '', '', '', ''),
         'stipple': ('stipple', '', '', '', ''),
         'tags': ('tags', '', '', '', ''),
         'width': ('width', '', '', '1.0', '1.0')}
        >
        The 'state' option can be set to 'normal', 'hidden' or 'disabled'. So
        if you want to make your canvas items look different when they are
        disabled, set the disabled* options and set 'state' to 'disabled'.
        >
        Matt
        I appologize. I didn't actually test this before posting the code, but
        if you have the mouse button down before entering an item on the
        canvas, even the active state doesn't seem apply. So, well, I hope
        someone finds this information useful, but I guess it isn't going to
        solve the original posters issue.

        Matt

        Comment

        • Hamish McKenzie

          #5
          inheritance question...


          I have this class:

          class Vector(object):
          TOL = 1e-5
          def __eq__( self, other, tolerance=TOL ):
          print tolerance


          shortened for clarity obviously. so I want to subclass this class like
          so:

          class BigVector(Vecto r)
          TOL = 100


          for example if I was working with large vectors which I knew would never
          be very close hence the large tolerance. this doesn't work however -
          the TOL class variable, while overridden in BigVector, is still using
          the Vector.TOL variable in the __eq__ method.


          which kinda makes sense to a certain degree, but how do I get the
          behaviour where doing:

          BigVector().__e q__( otherVec )


          prints 100 instead of 1e-5?

          does this question make sense? not sure how clearly I'm phrasing my
          question... any of you guys python experts?


          I *could* do this, but its ugly:

          class Vector(object):
          TOL = 1e-5
          def __eq__( self, other, tolerance=None ):
          if tolerance is None: tolerance = self.TOL
          print tolerance


          Comment

          • Guilherme Polo

            #6
            Re: inheritance question...

            On Fri, Jun 20, 2008 at 6:19 PM, Hamish McKenzie
            <hamish@valveso ftware.comwrote :
            >
            I have this class:
            >
            class Vector(object):
            TOL = 1e-5
            def __eq__( self, other, tolerance=TOL ):
            print tolerance
            >
            >
            shortened for clarity obviously. so I want to subclass this class like
            so:
            >
            class BigVector(Vecto r)
            TOL = 100
            >
            >
            for example if I was working with large vectors which I knew would never
            be very close hence the large tolerance. this doesn't work however -
            the TOL class variable, while overridden in BigVector, is still using
            the Vector.TOL variable in the __eq__ method.
            >
            >
            which kinda makes sense to a certain degree, but how do I get the
            behaviour where doing:
            >
            BigVector().__e q__( otherVec )
            No, don't do this. Just do "avector == othervector"
            >
            >
            prints 100 instead of 1e-5?
            >
            does this question make sense? not sure how clearly I'm phrasing my
            question... any of you guys python experts?
            >
            >
            I *could* do this, but its ugly:
            >
            class Vector(object):
            TOL = 1e-5
            def __eq__( self, other, tolerance=None ):
            if tolerance is None: tolerance = self.TOL
            print tolerance
            >
            class Vector(object):
            TOL = 1e-5
            def __eq__(self, other):
            print self.TOL


            --
            -- Guilherme H. Polo Goncalves

            Comment

            • Peter Pearson

              #7
              Re: Tkinter canvas drag/drop obstacle

              On Fri, 20 Jun 2008 13:41:35 -0300, Guilherme Polo <ggpolo@gmail.c omwrote:
              On Fri, Jun 20, 2008 at 1:11 PM, Peter Pearson <ppearson@nowhe re.invalidwrote :
              >Tkinter makes it very easy to drag jpeg images around on a
              >canvas, but I would like to have a "target" change color when
              >the cursor dragging an image passes over it. I seem to be
              >blocked by the fact that the callbacks that might tell the
              >target that the mouse has entered it (<Enter>, <Any-Enter>,
              >even <Motion>) aren't called if the mouse's button is down.
              >What am I missing? Have I failed to find the right Tkinter
              >document? Is Tkinter the wrong tool for this job? Thanks.
              >>
              >
              I believe the only way to achieve this is binding <Motionto the
              entire canvas, then checking if the x, y coords are inside the
              "target".
              Ugh. OK, thanks.

              --
              To email me, substitute nowhere->spamcop, invalid->net.

              Comment

              • Eric Brunel

                #8
                Re: inheritance question...

                Preamble: when posting a brand new question, you'd better not replying to
                an existing completely unrelated message. In most viewers, this will cause
                your message to appear in the thread for the original question and far
                less people will see it. So better create a brand new thread.

                On Fri, 20 Jun 2008 23:19:37 +0200, Hamish McKenzie
                <hamish@valveso ftware.comwrote :
                I have this class:
                >
                class Vector(object):
                TOL = 1e-5
                def __eq__( self, other, tolerance=TOL ):
                print tolerance
                >
                >
                shortened for clarity obviously. so I want to subclass this class like
                so:
                >
                class BigVector(Vecto r)
                TOL = 100
                >
                >
                for example if I was working with large vectors which I knew would never
                be very close hence the large tolerance. this doesn't work however -
                the TOL class variable, while overridden in BigVector, is still using
                the Vector.TOL variable in the __eq__ method.
                >
                >
                which kinda makes sense to a certain degree, but how do I get the
                behaviour where doing:
                >
                BigVector().__e q__( otherVec )
                >
                >
                prints 100 instead of 1e-5?
                >
                does this question make sense? not sure how clearly I'm phrasing my
                question... any of you guys python experts?
                There's just no way. The default values for function/method arguments are
                evaluated when the function definition is interpreted. When the __eq__
                method is defined, TOL is 1e-5, so that will be the value used in the
                method, whatever you may do afterwards.
                >
                I *could* do this, but its ugly:
                >
                class Vector(object):
                TOL = 1e-5
                def __eq__( self, other, tolerance=None ):
                if tolerance is None: tolerance = self.TOL
                print tolerance
                Well, ugliness is in the eye of the beholder... ;-) Even if you find it
                ugly, that's the Python way to do it.

                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...