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

查看:168
本文介绍了调整纵横比固定的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:

  • 内容框架使用固定的宽高比调整大小(假设始终需要为正方形)
  • 垫板框架占用了剩余的(垂直)空间

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

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

-丹尼尔

推荐答案

至少有两种方法可以解决此问题.最简单的IMO是将填充小部件作为内容小部件的容器,然后使用place显式设置内容小部件的宽度和高度.这是其中placegridpack首选的边缘情况之一.

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天全站免登陆