0

I ran into a problem with rendering an arc on tkinter canvas. (I am using recommended methods for scaling and scrolling the canvas, see my code...)

The code creates an arc on the canvas, its style is 'pieslice'. At first everything seems to work OK, but when I keep zooming-in to the curved edge of the shape, at some point it starts to mismatch with the other edges and eventually it disappears...

If I keep zooming even more, other edges disappear as well...

from tkinter import *

root = Tk()
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
cnv = Canvas(root)
cnv.grid(row=0, column=0, sticky='nswe')
cnv.create_arc(20, 20, 250, 250, start=0, extent=30)


def scroll_start(event):
    cnv.configure(cursor='fleur')
    cnv.scan_mark(event.x, event.y)


def scroll_move(event):
    cnv.scan_dragto(event.x, event.y, 1)


def scroll_end(event):
    cnv.configure(cursor='arrow')


def zoom(event):
    if event.delta > 0:
        cnv.scale('all', cnv.canvasx(event.x), cnv.canvasy(event.y), 1.1, 1.1)
    else:
        cnv.scale('all', cnv.canvasx(event.x), cnv.canvasy(event.y), 0.9, 0.9)


cnv.bind('<Button-3>', scroll_start)
cnv.bind('<B3-Motion>', scroll_move)
cnv.bind('<ButtonRelease-3>', scroll_end)
cnv.bind('<MouseWheel>', zoom)

root.mainloop()

Is there a way to fix this or am I getting to the limitations of tkinter? Thanks for any help.

1 Answers1

0

This is a partial answer that gives a measure of the limit where scaling seems to break down:

Adding a variable to record the scaling_factor, I can reach a 336 times magnification before observing the phenomena described by the OP. I speculate that this is maybe a float precision issue, or a limitation of canvas size, or some other reason?

from tkinter import *

root = Tk()
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
cnv = Canvas(root)
cnv.grid(row=0, column=0, sticky='nswe')
cnv.create_arc(20, 20, 250, 250, start=0, extent=30)

scaling_factor = 1


def scroll_start(event):
    cnv.configure(cursor='fleur')
    cnv.scan_mark(event.x, event.y)


def scroll_move(event):
    cnv.scan_dragto(event.x, event.y, 1)


def scroll_end(event):
    cnv.configure(cursor='arrow')


def zoom(event):
    global scaling_factor
    if event.delta > 0:
        cnv.scale('all', cnv.canvasx(event.x), cnv.canvasy(event.y), 1.1, 1.1)
        scaling_factor *= 1.1
        print(scaling_factor)
    else:
        cnv.scale('all', cnv.canvasx(event.x), cnv.canvasy(event.y), 1/1.1, 1/1.1)
        scaling_factor *= .9
        print(scaling_factor)

cnv.bind('<Button-3>', scroll_start)
cnv.bind('<B3-Motion>', scroll_move)
cnv.bind('<ButtonRelease-3>', scroll_end)
cnv.bind('<MouseWheel>', zoom)

root.mainloop()
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
  • I tried making the arc twice as big and then the problem appears with half the `scale_factor`... `cnv.create_arc(20, 20, 500, 500, start=0, extent=30)` – Vilém Pecen Sep 03 '18 at 07:12