Limit to the number of canvases in a top_level object?

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

Limit to the number of canvases in a top_level object?

Steve Solomon-3
Hello,

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

Steve

_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Limit to the number of canvases in a top_level object?

Lion Kimbro-2

  Would you (or someone) attach some sample code?

  That would make it easier to see if we can repro.


On Thu, Oct 13, 2011 at 10:49 AM, Steve Solomon <[hidden email]> wrote:
Hello,

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

Steve

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



_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Limit to the number of canvases in a top_level object?

Steve Solomon-3
Hi,
I'm a bit in the tall weeds, please excuse the mess (in the attached code).

steve

On Thu, Oct 13, 2011 at 12:27 PM, Lion Kimbro <[hidden email]> wrote:

  Would you (or someone) attach some sample code?

  That would make it easier to see if we can repro.


On Thu, Oct 13, 2011 at 10:49 AM, Steve Solomon <[hidden email]> wrote:
Hello,

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

Steve

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




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

palettebuilder.py (10K) Download Attachment
test.py (3K) Download Attachment
colorservices.py (906 bytes) Download Attachment
classpoint.py (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Limit to the number of canvases in a top_level object?

Peter Otten
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