I am trying to create a canvas with one useful function for me. I need to make my program understand when object on canvas is too big so this object will collide with borders of canvas and automatically will decrise size of object. I know that canvas can't change size of objects, canvas just change coordinates of object.
So, I did almost everything, and it works, but only first time. If I create a rectangle with bigger sizes again, my program will not change coordinates again. With .bbox function we can see, that coordinates are still the same. I think that after "If statment" I need to update new position of coordinates.
Better just to take my code and try it. For example: maximum size for height is 356mm and for width is 473mm. If you will write into height 357mm or into width 474mm -> function "create" will automatically change coordinates with ".scale", but only once.
My idea is to write different sizes of the rectangle and I always want to see my rectangle in the middle of the canvas. Not to allow this rectangle touch borders, but if it did -> change coordinates and make it smaller.
How I can make it each time when object touching borders?
My code:
from tkinter import *
from tkinter import ttk
import tkinter as tk
create_win = tk.Tk()
create_win.title("Sample canvas")
create_win.geometry("500x550")
create_win.resizable(False, False)
create_win.configure(background="white")
create_win.columnconfigure(0, weight=1)
create_win.rowconfigure(0, weight=1)
main_frame = LabelFrame(create_win, text="Sample Canvas", background="white")
main_frame.grid(row=0, column=0, sticky=NW SE, padx=10, pady=[0,10])
c = Canvas(main_frame, background="white", cursor="crosshair")
c.pack(fill=BOTH, expand=True)
entry_fields = LabelFrame(create_win, text="Enter data", background="white")
entry_fields.grid(row=1, column=0, sticky=NW SE, padx=10, pady=[0,10])
width_lbl = Label(entry_fields, text="Width", font=("Calibri Light", 14), background="white")
width_lbl.grid(row=0, column=0)
height_lbl = Label(entry_fields, text="Height", font=("Calibri Light", 14), background="white")
height_lbl.grid(row=0, column=1)
width_entry = Entry(entry_fields, font=("Calibri Light", 14), bd=2, justify=CENTER, width=22)
width_entry.grid(row=1, column=0, padx=[10,0], pady=[5,10])
height_entry = Entry(entry_fields, font=("Calibri Light", 14), bd=2, justify=CENTER, width=22)
height_entry.grid(row=1, column=1, padx=[4,0], pady=[5,10])
create_win.update()
canvas_w = c.winfo_width()
canvas_h = (c.winfo_height() - 60)
#print(canvas_w)
#print(canvas_h)
def create():
width_entry_int = int(float(width_entry.get()))
height_entry_int = int(float(height_entry.get()))
x1 = (canvas_w - width_entry_int) / 2
y1 = (canvas_h - height_entry_int) / 2
x2 = x1 int(float(width_entry.get()))
y2 = y1 int(float(height_entry.get()))
c.delete("all")
rect = c.create_rectangle(x1, y1, x2, y2, fill="red", outline="red")
data = c.bbox(rect)
print(data)
if float(data[0]) <= 0 or float(data[1]) <= 0:
c.scale("all", ((x1 x2) / 2), ((y1 y2) / 2), 0.5, 0.5)
apply_btn = Button(create_win, text="Apply", font=("Calibri Light", 14), padx=5, pady=5, bd=0, background="#747d8c", fg="white", cursor="hand2", command=create)
apply_btn.grid(row=2, column=0, pady=[0,10])
create_win.mainloop()
Thanks in advance!
CodePudding user response:
Okay now, you should change this part
data = c.bbox(rect)
if float(data[0]) <= 0 or float(data[1]) <= 0:
print(data)
c.scale("all", ((x1 x2) / 2), ((y1 y2) / 2), 0.5, 0.5)
into this one:
data = c.bbox(rect)
while float(data[0]) <= 0 or float(data[1]) <= 0:
c.scale("all", ((x1 x2) / 2), ((y1 y2) / 2), 0.5, 0.5)
data = c.bbox(rect)
Now until it doesn't touches walls, it rescales.