#python-3.x #object #tkinter #canvas #resize
Вопрос:
from tkinter import *
root=Tk()
root.geometry('700x700')
canvas=Canvas(root,bg='white',height=600,width=600)
canvas.pack()
canvas.create_line(0,0,100,0)
canvas.create_line(100,0,100,100)
canvas.create_line(100,100,0,100)
canvas.create_line(0,100,0,0)
mainloop()
вот пример проблемы. в этом случае я хочу изменить размер всех линий вместе и совместить их с окном холста. как это можно сделать? Мне нужно общее решение для любой группы объектов холста,таких как овал,многоугольник, дуга…и т. Д
Ответ №1:
Попробуйте это:
import tkinter as tk
def resize_to_fill(canvas):
global bbox, xfactor, yfactor, factor, x, y # For debug only
# Get the [minx, miny, maxx, maxy] of all of the canvas items:
bbox = [float("inf"), float("inf"), float("-inf"), float("-inf")]
for id in canvas.find_all():
x1, y1, x2, y2 = canvas.bbox(id)
bbox[0] = min(bbox[0], x1)
bbox[1] = min(bbox[1], y1)
bbox[2] = max(bbox[2], x2)
bbox[3] = max(bbox[3], y2)
# This is needed to get the width and height of the canvas
canvas.update()
# Calculate the scale factors
xfactor = canvas.winfo_width() / (bbox[2]-bbox[0])
yfactor = canvas.winfo_height() / (bbox[3]-bbox[1])
canvas.moveto("all", 0, 0)
canvas.scale("all", 0, 0, xfactor, yfactor)
root = tk.Tk()
root.resizable(False, False)
canvas = tk.Canvas(root, bg="white", width=600, height=600,
highlightthickness=0)
canvas.pack()
# Change this to `False` if you want to test the second example
if True:
canvas.create_line(0, 0, 100, 0, fill="red")
canvas.create_line(100, 0, 100, 100, fill="blue")
canvas.create_line(100, 100, 0, 100, fill="black")
canvas.create_line(0, 100, 0, 0, fill="green")
else:
canvas.create_line(50, 50, 100, 50, fill="red")
canvas.create_line(100, 50, 100, 100, fill="blue")
canvas.create_line(100, 100, 50, 100, fill="black")
canvas.create_line(50, 100, 50, 50, fill="green")
button = tk.Button(root, text="Resize to fit canvas",
command=lambda: resize_to_fill(canvas))
button.pack(fill="x")
root.mainloop()
В основном это математика, но в основном я занимаюсь тем, что:
- Получите
min(x)
,min(y)
,max(x)
иmax(y)
всех объектов - Рассчитайте коэффициенты x и y
- Переместите все объекты
(0, 0)
, чтобы упростить масштабирование - Масштабирование всего объекта по
xfactor
иyfactor
от(0, 0)
Примечания:
- Он не сохраняет соотношение сторон.
- Иногда он оставляет зазор между краями экрана. Я понятия не имею, почему
Комментарии:
1. Спасибо,это отлично работает для данного примера. Но в большинстве случаев при изменении размера объекты на холсте изменяются за пределы размера холста. Можете ли вы дать обобщенный код изменения размера для любого заданного объекта на холсте?
2. @abdullathahir Я сделал так, чтобы размер холста соответствовал размеру всех объектов внутри холста. Если я сделаю так, чтобы его размер соответствовал одному объекту, остальные объекты не будут видны. Что вы нанесли на холст, чтобы он не работал? Возможно, мой код ошибочен. Кроме того, он не сохраняет соотношение сторон, поэтому ваши объекты могут быть сведены в линию.
Ответ №2:
пробовать:
x = 600
y = 600
tk = Tk()
canvas=Canvas(tk, bg='white', height=x, width=y)
canvas.pack()
canvas.create_line(x a certain number, y a certain number, x a certain number, y a certain number)
tk.mainloop()
Комментарии:
1. Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и/или почему он решает проблему, повысит долгосрочную ценность ответа.