Thank you all,<br>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.<br>Steve<br><br><div class="gmail_quote">On Mon, Oct 17, 2011 at 3:00 AM, <span dir="ltr"><<a href="mailto:tkinter-discuss-request@python.org">tkinter-discuss-request@python.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Send Tkinter-discuss mailing list submissions to<br>
<a href="mailto:tkinter-discuss@python.org">tkinter-discuss@python.org</a><br>
<br>
To subscribe or unsubscribe via the World Wide Web, visit<br>
<a href="http://mail.python.org/mailman/listinfo/tkinter-discuss" target="_blank">http://mail.python.org/mailman/listinfo/tkinter-discuss</a><br>
or, via email, send a message with subject or body 'help' to<br>
<a href="mailto:tkinter-discuss-request@python.org">tkinter-discuss-request@python.org</a><br>
<br>
You can reach the person managing the list at<br>
<a href="mailto:tkinter-discuss-owner@python.org">tkinter-discuss-owner@python.org</a><br>
<br>
When replying, please edit your Subject line so it is more specific<br>
than "Re: Contents of Tkinter-discuss digest..."<br>
<br>
<br>
Today's Topics:<br>
<br>
1. Re: Limit to the number of canvases in a top_level object?<br>
(Peter Otten)<br>
<br>
<br>
----------------------------------------------------------------------<br>
<br>
Message: 1<br>
Date: Sun, 16 Oct 2011 15:43:26 +0200<br>
From: Peter Otten <__<a href="mailto:peter__@web.de">peter__@web.de</a>><br>
To: <a href="mailto:tkinter-discuss@python.org">tkinter-discuss@python.org</a><br>
Subject: Re: [Tkinter-discuss] Limit to the number of canvases in a<br>
top_level object?<br>
Message-ID: <j7emvl$m7$<a href="mailto:1@dough.gmane.org">1@dough.gmane.org</a>><br>
Content-Type: text/plain; charset="ISO-8859-1"<br>
<br>
Steve Solomon wrote:<br>
<br>
>>> Is there a limit to the number of canvases in a top_level object -- one<br>
>>> maybe ? I have been trying to solve this problem with an application for<br>
>>> several weeks. In the application I have two canvases, each with a grid<br>
>>> of rectangle objects. They display perfectly but when I try to interact<br>
>>> with the rectangles they behave anomalously. Using<br>
>>> canvas.find_closest(event.x, event.y) the rectangles in the first drawn<br>
>>> canvas behave normally, allowing configuring each, but within the second<br>
>>> canvas the rectangles report back the id of only one of the rectangles<br>
>>> and an attempt to change the fill-color of any one is applied only to<br>
>>> the last item in the grid.<br>
>>><br>
>>> Your thoughts would be appreciated, thank you<br>
<br>
> I'm a bit in the tall weeds, please excuse the mess (in the attached<br>
> code).<br>
<br>
The best time to clean up your code is always right now; the second best<br>
time is when you run into an error ;)<br>
<br>
> from Tkinter import *<br>
> import random<br>
> import palettebuilder as pb<br>
> from colorservices import getHSV<br>
><br>
> def randomColors(count=1, sorted=False):<br>
> "returns list of color strings in #nnnnnn hexidecimal format"<br>
> rtn = []<br>
> for x in range(count):<br>
> intgr = random.randrange(0, 16777215, 1)<br>
> hex = "#{:0>6X}".format(intgr)<br>
> rtn.append(hex)<br>
> if sorted:<br>
> "the folowing should be sorted by ..."<br>
> # rtn.sort(key=lambda rtn: getHSV(rtn)[2]) #...value<br>
> rtn.sort(key=lambda rtn: getHSV(rtn)) #...full HSV<br>
> return rtn<br>
><br>
> class test(Toplevel):<br>
> def __init__(self):<br>
> Toplevel.__init__(self)<br>
> self.config(height = 500, width = 500)<br>
> self.activeCanvas = None<br>
> self.bind("<KeyPress-c>", self.reportXY)<br>
> size = 180<br>
> frameOne = Frame(self, height = 200, width =200, bg = "pink")<br>
> self.canvasOne = Canvas(frameOne, height=size, width=size,<br>
background="#bababa")<br>
> self.canvasOne.grid(row = 0, column = 0, sticky = W )<br>
> frameTwo = Frame(self, height = 200, width =200, bg="light blue")<br>
> self.canvasTwo = Canvas(frameTwo, height=size, width=size,<br>
bg='#bababa')<br>
> self.canvasTwo.grid(row = 1, column = 1)<br>
> self.canvasOne.bind("<Enter>", self.makeOneActive)<br>
> self.canvasTwo.bind("<Enter>", self.makeTwoActive)<br>
> frameOne.grid(row = 0, column = 0, sticky = W )<br>
> frameTwo.grid(row = 1, column = 1, sticky = E )<br>
> colors = randomColors(64, sorted = True)<br>
> pb.DrawPalette(self.canvasOne, colors, columns = 8)<br>
> colors = randomColors(64, sorted = True)<br>
> pb.DrawPalette(self.canvasTwo, colors, columns = 8)<br>
><br>
> def makeOneActive(self, event):<br>
> self.activeCanvas = self.canvasOne<br>
> print "one = active self.activeCanvas>>>", type(self.activeCanvas)<br>
><br>
> def makeTwoActive(self, event):<br>
> self.activeCanvas = self.canvasTwo<br>
> print "two = active self.activeCanvas>>>", type(self.activeCanvas)<br>
><br>
> def reportXY(self, event):<br>
> print event.x, event.y<br>
> item=self.activeCanvas.find_closest(event.x, event.y)<br>
> print self.activeCanvas.itemcget(item, "tags"), "item>>", item<br>
> self.activeCanvas.itemconfigure(item, fill = "red")<br>
><br>
> root = Tk()<br>
> root.withdraw()<br>
> test()<br>
> #for x in range(10):<br>
> # print randomColors(10)<br>
> # print "\n"<br>
> root.mainloop()<br>
><br>
<br>
You bind the reportXY() method to an event triggered by your Toplevel<br>
subclass, so the event instance contains coordinates relative to the test<br>
widget. On the other hand the Canvas.find_closest() method expects<br>
coordinates in terms of the canvas widget. The difference doesn't matter for<br>
canvasOne which is located at the origin of the toplevel, but gives wrong<br>
results for canvasTwo with its non-zero offset.<br>
<br>
While the diagnosis was easy it took me a while to find a way to convert<br>
between the two coordinate systems. The following seems to work:<br>
<br>
def reportXY(self, event):<br>
canvas = self.activeCanvas<br>
<br>
dx = self.winfo_rootx() - canvas.winfo_rootx()<br>
dy = self.winfo_rooty() - canvas.winfo_rooty()<br>
<br>
x = event.x + dx<br>
y = event.y + dy<br>
<br>
print "before", event.x, event.y<br>
print "after", x, y<br>
<br>
item = canvas.find_closest(x, y)<br>
print canvas.itemcget(item, "tags"), "item>>", item<br>
canvas.itemconfigure(item, fill="red")<br>
<br>
Let me know if you find a better way or run into a problem with my approach.<br>
<br>
<br>
<br>
------------------------------<br>
<br>
_______________________________________________<br>
Tkinter-discuss mailing list<br>
<a href="mailto:Tkinter-discuss@python.org">Tkinter-discuss@python.org</a><br>
<a href="http://mail.python.org/mailman/listinfo/tkinter-discuss" target="_blank">http://mail.python.org/mailman/listinfo/tkinter-discuss</a><br>
<br>
<br>
End of Tkinter-discuss Digest, Vol 92, Issue 7<br>
**********************************************<br>
</blockquote></div><br>