调整具有固定纵横比的 Tkinter 框架的大小 [英] Resizing Tkinter Frames with fixed aspect-ratio

查看:36
本文介绍了调整具有固定纵横比的 Tkinter 框架的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法来使 Tkinter 框架在调整大小时表现得有点像这样:

I'm looking for a way to make Tkinter Frames behave somewhat like this while resizing:

from Tkinter import *
w = Tk()
w.aspect(1,1,1,1)
w.mainloop()

所以我想要这里的代码:

So I'd like this code here:

import Tkinter as tk
from Tkconstants import *
r=tk.Tk()
content_frame=tk.Frame(r,borderwidth=5,relief=GROOVE)
content_frame.grid(row=0,column=0,sticky=(N,S,E,W))
tk.Label(content_frame,text='content').pack()
pad_frame=tk.Frame(r,borderwidth=5,relief=GROOVE)
pad_frame.grid(row=1,column=0,sticky=(N,S,E,W))
tk.Label(pad_frame,text='-pad-').pack()
r.rowconfigure(0, weight=1)
r.rowconfigure(1, weight=1)
r.columnconfigure(0, weight=1)
r.mainloop()

它基本上创建了 2 个框架,一个应该包含一些内容(在我的应用程序中,这个框架包含一个可以调整大小的 mathplotlib 图)和一个仅用于填充.

which basically creates 2 frames, one that's supposed to hold some content (in my application this frame holds a mathplotlib graph that can be resized) and one simply for padding.

按照以下规则调整大小:

To behave on resizing following these rules:

  • 内容框架以固定的纵横比调整大小(假设它始终需要是方形的)
  • pad 框架占据了剩余的(垂直)空间

有什么想法吗?我已经阅读了一段时间的手册,似乎找不到合适的东西.

Any ideas? I've been reading manuals for a while now and can't seem to find something fitting.

-丹尼尔

推荐答案

至少有几种方法可以解决这个问题.最简单的 IMO 是让您的填充小部件成为内容小部件的容器,然后使用 place 显式设置内容小部件的宽度和高度.这是 place 优于 gridpack 的边缘情况之一.

There are at least a couple ways to solve this. The simplest, IMO, is to have your padding widget be a container for your content widget, and then you explicitly set the width and height of the content widget using place. This is one of the edge cases where place is preferred over grid or pack.

在以下示例中,我创建了一个函数,该函数可让您传入内容框架、填充框架和纵横比.然后它通过纵横比和容器的大小来限制内容框架的大小.它将使内容窗口在 X 维度上填充容器,然后适当地设置高度.如果生成的窗口太高而不可见,它将最大高度设置为容器的高度并改为调整宽度.

In the following example I've created a function which lets you pass in a content frame, a padding frame, and an aspect ratio. It then constrains the size of the content frame by the aspect ratio and the size of the container. It will make the content window fill the container in the X dimension and then set the height appropriately. If the resulting window is too tall to be visible, it sets the max height to the height of the container and adjusts the width instead.

我已经尝试保持问题中的大部分代码完整无缺,即使这不是我通常选择的编码方式.我为小部件指定了不同的颜色,以便更容易看到正在发生的事情.

I've tried to keep most of the code from the question intact, even though this isn't exactly how I would normally choose to code it. I've given the widgets distinct colors so it's easier to see what is happening.

import Tkinter as tk
from Tkconstants import *
r=tk.Tk()

def set_aspect(content_frame, pad_frame, aspect_ratio):
    # a function which places a frame within a containing frame, and
    # then forces the inner frame to keep a specific aspect ratio

    def enforce_aspect_ratio(event):
        # when the pad window resizes, fit the content into it,
        # either by fixing the width or the height and then
        # adjusting the height or width based on the aspect ratio.

        # start by using the width as the controlling dimension
        desired_width = event.width
        desired_height = int(event.width / aspect_ratio)

        # if the window is too tall to fit, use the height as
        # the controlling dimension
        if desired_height > event.height:
            desired_height = event.height
            desired_width = int(event.height * aspect_ratio)

        # place the window, giving it an explicit size
        content_frame.place(in_=pad_frame, x=0, y=0, 
            width=desired_width, height=desired_height)

    pad_frame.bind("<Configure>", enforce_aspect_ratio)

pad_frame = tk.Frame(borderwidth=0, background="bisque", width=200, height=200)
pad_frame.grid(row=0, column=0, sticky="nsew", padx=10, pady=20)
content_frame=tk.Frame(r,borderwidth=5,relief=GROOVE, background="blue")
tk.Label(content_frame,text='content').pack()
set_aspect(content_frame, pad_frame, aspect_ratio=2.0/1.0) 
r.rowconfigure(0, weight=1)
r.columnconfigure(0, weight=1)

r.mainloop()

如果包含小部件的内容可以轻松调整到容器的大小,这将最有效.如果其中有一个复杂的小部件布局,当窗口缩小到其自然大小以下时,如果它们不适合某些小部件,它们可能会被砍掉.

This will work best if the containing widget has contents that easily adjust to the size of the container. If there is a complex layout of widgets within, some widgets could get chopped off if they don't fit when the window is shrunk below its natural size.

这篇关于调整具有固定纵横比的 Tkinter 框架的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆