【问题标题】:How to fit objects in the canvas with the canvas sizeh in tkinter?如何使画布中的对象与 tkinter 中的画布大小相匹配?
【发布时间】:2021-07-06 08:52:56
【问题描述】:
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()

这是一个示例问题。在此,我想一起调整所有线条的大小并将它们与画布窗口相匹配。如何做到这一点?我想要任何一组画布对象的通用解决方案,例如椭圆形、多边形、弧形...等

【问题讨论】:

    标签: python-3.x object tkinter canvas resize


    【解决方案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) 以使缩放更容易
    • 通过xfactoryfactor(0, 0) 缩放所有对象

    注意事项:

    • 它不保持纵横比。
    • 有时它会在屏幕边缘之间留下空隙。我不知道为什么

    【讨论】:

    • 谢谢,它适用于给定的例子。但在大多数情况下,当调整大小时,画布中的对象调整大小超出了画布大小。你能为任何给定对象提供一个通用的调整大小代码画布?
    • @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()
    

    【讨论】:

    • 虽然此代码可以回答问题,但提供有关 如何 和/或 为什么 解决问题的附加上下文将改善答案的长期价值。
    猜你喜欢
    • 2015-04-21
    • 1970-01-01
    • 2017-08-07
    • 2021-04-28
    • 2015-06-01
    • 2017-04-08
    • 2019-04-26
    • 1970-01-01
    • 2018-11-05
    相关资源
    最近更新 更多