Re: Tkinter-discuss Digest, Vol 92, Issue 7

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: Tkinter-discuss Digest, Vol 92, Issue 7

Steve Solomon-3
Thank you all,
Peter Otten's patch worked right off the bat. Now that Peter explained the core of the problem I'll be able to tinker with the code to dig deeper.
Steve

On Mon, Oct 17, 2011 at 3:00 AM, <[hidden email]> wrote:
Send Tkinter-discuss mailing list submissions to
       [hidden email]

To subscribe or unsubscribe via the World Wide Web, visit
       http://mail.python.org/mailman/listinfo/tkinter-discuss
or, via email, send a message with subject or body 'help' to
       [hidden email]

You can reach the person managing the list at
       [hidden email]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Tkinter-discuss digest..."


Today's Topics:

  1. Re: Limit to the number of canvases in a  top_level object?
     (Peter Otten)


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

Message: 1
Date: Sun, 16 Oct 2011 15:43:26 +0200
From: Peter Otten <__[hidden email]>
To: [hidden email]
Subject: Re: [Tkinter-discuss] Limit to the number of canvases in a
       top_level object?
Message-ID: <j7emvl$m7$[hidden email]>
Content-Type: text/plain; charset="ISO-8859-1"

Steve Solomon wrote:

>>> Is there  a limit to the number of canvases in a top_level object -- one
>>> maybe ? I have been trying to solve this problem with an application for
>>> several weeks. In the application I have two canvases, each with a grid
>>> of rectangle objects. They display perfectly but when I try to interact
>>> with the rectangles they behave anomalously. Using
>>> canvas.find_closest(event.x, event.y) the rectangles in the first drawn
>>> canvas behave normally, allowing configuring each, but within the second
>>> canvas the rectangles report back the id of only one of the rectangles
>>> and an attempt to change the fill-color of any one is applied only to
>>> the last item in the grid.
>>>
>>> Your thoughts would be appreciated, thank you

> I'm a bit in the tall weeds, please excuse the mess (in the attached
> code).

The best time to clean up your code is always right now; the second best
time is when you run into an error ;)

> from Tkinter import *
> import random
> import palettebuilder as pb
> from colorservices import getHSV
>
> def randomColors(count=1, sorted=False):
>     "returns list of color strings in #nnnnnn hexidecimal format"
>     rtn = []
>     for x in range(count):
>         intgr = random.randrange(0, 16777215, 1)
>         hex = "#{:0>6X}".format(intgr)
>         rtn.append(hex)
>     if sorted:
>         "the folowing should be sorted by ..."
> #        rtn.sort(key=lambda rtn: getHSV(rtn)[2]) #...value
>         rtn.sort(key=lambda rtn: getHSV(rtn)) #...full HSV
>     return rtn
>
> class test(Toplevel):
>     def __init__(self):
>         Toplevel.__init__(self)
>         self.config(height = 500, width = 500)
>         self.activeCanvas = None
>         self.bind("<KeyPress-c>", self.reportXY)
>         size = 180
>         frameOne = Frame(self, height = 200, width =200, bg = "pink")
>         self.canvasOne = Canvas(frameOne, height=size, width=size,
background="#bababa")
>         self.canvasOne.grid(row = 0, column = 0, sticky = W )
>         frameTwo = Frame(self, height = 200, width =200, bg="light blue")
>         self.canvasTwo = Canvas(frameTwo, height=size, width=size,
bg='#bababa')
>         self.canvasTwo.grid(row = 1, column = 1)
>         self.canvasOne.bind("<Enter>", self.makeOneActive)
>         self.canvasTwo.bind("<Enter>", self.makeTwoActive)
>         frameOne.grid(row = 0, column = 0, sticky = W )
>         frameTwo.grid(row = 1, column = 1, sticky = E )
>         colors = randomColors(64, sorted = True)
>         pb.DrawPalette(self.canvasOne, colors, columns = 8)
>         colors = randomColors(64, sorted = True)
>         pb.DrawPalette(self.canvasTwo, colors, columns = 8)
>
>     def makeOneActive(self, event):
>         self.activeCanvas = self.canvasOne
>         print "one = active self.activeCanvas>>>", type(self.activeCanvas)
>
>     def makeTwoActive(self, event):
>         self.activeCanvas = self.canvasTwo
>         print "two = active self.activeCanvas>>>", type(self.activeCanvas)
>
>     def reportXY(self, event):
>         print event.x, event.y
>         item=self.activeCanvas.find_closest(event.x, event.y)
>         print self.activeCanvas.itemcget(item, "tags"), "item>>", item
>         self.activeCanvas.itemconfigure(item, fill = "red")
>
> root = Tk()
> root.withdraw()
> test()
> #for x in range(10):
> #    print randomColors(10)
> #    print "\n"
> root.mainloop()
>

You bind the reportXY() method to an event triggered by your Toplevel
subclass, so the event instance contains coordinates relative to the test
widget. On the other hand the Canvas.find_closest() method expects
coordinates in terms of the canvas widget. The difference doesn't matter for
canvasOne which is located at the origin of the toplevel, but gives wrong
results for canvasTwo with its non-zero offset.

While the diagnosis was easy it took me a while to find a way to convert
between the two coordinate systems. The following seems to work:

   def reportXY(self, event):
       canvas = self.activeCanvas

       dx = self.winfo_rootx() - canvas.winfo_rootx()
       dy = self.winfo_rooty() - canvas.winfo_rooty()

       x = event.x + dx
       y = event.y + dy

       print "before", event.x, event.y
       print "after", x, y

       item = canvas.find_closest(x, y)
       print canvas.itemcget(item, "tags"), "item>>", item
       canvas.itemconfigure(item, fill="red")

Let me know if you find a better way or run into a problem with my approach.



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

_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss


End of Tkinter-discuss Digest, Vol 92, Issue 7
**********************************************


_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss