here2share

# tk_canvas_zoom.py

Oct 4th, 2025
286
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.55 KB | None | 0 0
  1. # tk_canvas_zoom.py
  2.  
  3. import tkinter as tk
  4.  
  5. def create_xcanvas(rootwin, **opt):
  6.     width = opt.get("width", 1000)
  7.     height = opt.get("height", 600)
  8.     bg = opt.get("bg", "white")
  9.     scrollbars = opt.get("scrollbars", True)
  10.     scalewidget = opt.get("scalewidget", True)
  11.     x_axis = opt.get("x_axis", 7)
  12.     y_axis = opt.get("y_axis", 7)
  13.  
  14.     region = (-50, -50, width, height)
  15.     rootframe = tk.Frame(rootwin, width=width, height=height, bg=bg)
  16.     rootframe.pack(expand=True, fill=tk.BOTH)
  17.    
  18.     canvas = tk.Canvas(rootframe, width=width, height=height, bg=bg, scrollregion=region)
  19.     canvas.config(highlightthickness=0)
  20.  
  21.     if scrollbars:
  22.         setup_scrollbars(canvas, rootframe)
  23.  
  24.     canvas.pack(side=tk.LEFT, expand=True, fill=tk.BOTH)
  25.  
  26.     scalewidget_obj = tk.Scale(rootframe, from_=1, to=3000, length=500,
  27.                                orient=tk.VERTICAL, font="Consolas 6",
  28.                                command=lambda p: resize_canvas(canvas, region, p))
  29.     scalewidget_obj.set(100)
  30.    
  31.     if scalewidget:
  32.         scalewidget_obj.pack(side=tk.TOP, fill=tk.Y, expand=False)
  33.     else:
  34.         scalewidget_obj.place(x=100000, y=100000)
  35.    
  36.     canvas.xview_moveto(0)
  37.     canvas.yview_moveto(0)
  38.    
  39.     if x_axis or y_axis:
  40.         draw_axis(canvas, x_axis, y_axis)
  41.    
  42.     setup_bindings(canvas, rootwin, scalewidget_obj)
  43.    
  44.     canvas.region = region
  45.     canvas.rootwin = rootwin
  46.     canvas.scalewidget = scalewidget_obj
  47.    
  48.     return canvas
  49.  
  50. def setup_scrollbars(canvas, rootframe):
  51.     sbarV = tk.Scrollbar(rootframe, orient=tk.VERTICAL)
  52.     sbarH = tk.Scrollbar(rootframe, orient=tk.HORIZONTAL)
  53.     sbarV.config(command=canvas.yview)
  54.     sbarH.config(command=canvas.xview)
  55.     canvas.config(yscrollcommand=sbarV.set)
  56.     canvas.config(xscrollcommand=sbarH.set)
  57.     sbarV.pack(side=tk.RIGHT, fill=tk.Y)
  58.     sbarH.pack(side=tk.BOTTOM, fill=tk.X)
  59.  
  60. def setup_bindings(canvas, rootwin, scalewidget):
  61.     canvas.bind("<Control-MouseWheel>", lambda e: on_ctrl_mousewheel(e, scalewidget))
  62.     canvas.bind("<Alt-MouseWheel>", lambda e: on_alt_mousewheel(e, scalewidget))
  63.     canvas.bind("<MouseWheel>", lambda e: canvas.yview_scroll(int(-1*(e.delta/120)), "units"))
  64.     canvas.bind("<Shift-MouseWheel>", lambda e: canvas.xview_scroll(int(-1*(e.delta/120)), "units"))
  65.     canvas.bind("f", lambda e: scalewidget.set(100))
  66.     canvas.bind("<Home>", lambda e: scalewidget.set(100))
  67.     canvas.bind("<Up>", lambda e: canvas.yview_scroll(-1, "units"))
  68.     canvas.bind("<Down>", lambda e: canvas.yview_scroll(1, "units"))
  69.     canvas.bind("<Left>", lambda e: canvas.xview_scroll(-1, "units"))
  70.     canvas.bind("<Right>", lambda e: canvas.xview_scroll(1, "units"))
  71.     canvas.bind("<Prior>", lambda e: canvas.yview_scroll(-1, "pages"))
  72.     canvas.bind("<Next>", lambda e: canvas.yview_scroll(1, "pages"))
  73.     canvas.bind("<Shift-Prior>", lambda e: canvas.xview_scroll(1, "pages"))
  74.     canvas.bind("<Shift-Next>", lambda e: canvas.xview_scroll(-1, "pages"))
  75.  
  76. def on_ctrl_mousewheel(event, scalewidget):
  77.     s = scalewidget.get()
  78.     s += 15 if event.delta > 0 else -15
  79.     scalewidget.set(s)
  80.  
  81. def on_alt_mousewheel(event, scalewidget):
  82.     s = scalewidget.get()
  83.     s += 5 if event.delta > 0 else -5
  84.     scalewidget.set(s)
  85.  
  86. def resize_canvas(canvas, region, percent):
  87.     x1, y1, x2, y2 = region
  88.     canvas_breadth = max(x2-x1, y2-y1)
  89.     _region = canvas.config('scrollregion')[4].split()
  90.     region_vals = tuple(float(x) for x in _region)
  91.     x1, y1, x2, y2 = region_vals
  92.     breadth = max(x2-x1, y2-y1)
  93.    
  94.     if breadth == 0:
  95.         return
  96.    
  97.     r = float(percent) / 100
  98.     if r < 0.01 or r > 30:
  99.         return
  100.    
  101.     s = r / (float(breadth) / canvas_breadth)
  102.     canvas.scale('all', 0, 0, s, s)
  103.     nregion = tuple(x*r for x in region)
  104.     canvas.config(scrollregion=nregion)
  105.  
  106. def draw_axis(canvas, m, n):
  107.     canvas.create_line(-40, 0, 100*m, 0, width=1, fill='black', arrow='last')
  108.     canvas.create_line(0, -40, 0, 100*n, width=1, fill='black', arrow='last')
  109.     for i in range(1, m):
  110.         canvas.create_line(100*i, -5, 100*i, 0, width=1, fill='black')
  111.         canvas.create_text(100*i, -5, text=str(100*i), font='Consolas 8', anchor='s')
  112.     for i in range(1, n):
  113.         canvas.create_line(-5, 100*i, 0, 100*i, width=1, fill='black')
  114.         canvas.create_text(-7, 100*i, text=str(100*i), font='Consolas 8', anchor='e')
  115.  
  116. def show_canvas(canvas, force=False):
  117.     if force or not canvas.winfo_ismapped():
  118.         canvas.rootwin.iconify()
  119.         canvas.rootwin.update()
  120.         canvas.rootwin.deiconify()
  121.         canvas.rootwin.lift()
  122.  
  123. def hide_canvas(canvas):
  124.     canvas.rootwin.iconify()
  125.  
  126. def xcanvas_test():
  127.     rootwin1 = tk.Tk()
  128.     c1 = create_xcanvas(rootwin1, width=1000, height=800, bg="white")
  129.     c1.create_rectangle(100, 120, 400, 230, width=2, outline='blue', fill='yellow')
  130.     c1.create_rectangle(400, 320, 600, 530, width=2, outline='blue', fill='yellow')
  131.     c1.create_oval(400, 320, 600, 530, width=2, outline='blue', fill='cyan')
  132.     c1.create_line(200, 50, 500, 430, width=3, fill='blue')
  133.  
  134.     rootwin2 = tk.Tk()
  135.     c2 = create_xcanvas(rootwin2, scrollbars=False, scalewidget=False, x_axis=0, y_axis=0, width=1000, height=800, bg="cornsilk")
  136.     c2.create_rectangle(100, 120, 400, 230, width=2, outline='red', fill='yellow')
  137.     c2.create_oval(100, 120, 400, 230, width=2, outline='red', fill='cyan')
  138.     c2.create_rectangle(400, 320, 600, 530, width=2, outline='red', fill='yellow')
  139.     c2.create_line(200, 50, 500, 430, width=3, fill='red')
  140.  
  141.     tk.mainloop()
  142.  
  143. xcanvas_test()
  144.  
Advertisement
Add Comment
Please, Sign In to add comment