简体   繁体   English

在 tkinter 中调整输入框的大小

[英]Resize entry box in tkinter

The following MWE is for a window with horizontal and vertical scrollbars.以下 MWE 适用于具有水平和垂直滚动条的窗口。 The window contains an entry box in which the current working directory is displayed.该窗口包含一个显示当前工作目录的输入框。 However, the text in the entry box cannot all be seen as the box is too small.但是由于输入框太小,无法全部看到输入框内的文字。 I would like to be able to display more of this text as the user enlarges the window.当用户放大窗口时,我希望能够显示更多的文本。 How can I adapt the following example so that the Entry box (defined in UserFileInput) resizes with the window?如何调整以下示例,以便输入框(在 UserFileInput 中定义)随窗口大小调整? I have tried using window.grid_columnconfigure (see below), however this doesn't have any effect.我曾尝试使用window.grid_columnconfigure (见下文),但这没有任何效果。 It seems to be a problem with using the canvas, as previously I was able to get the Entry boxes to resize, however I need the canvas in order to place the horizontal and vertical scrollbars on the window.使用画布似乎是一个问题,因为以前我能够调整条目框的大小,但是我需要画布才能将水平和垂直滚动条放置在窗口上。

window.grid(row=0, column=0, sticky='ew')
window.grid_columnconfigure(0, weight=1)

(and also with column = 1) but this doesn't have an effect. (还有列 = 1),但这没有效果。

import Tkinter as tk
import tkFileDialog
import os

class AutoScrollbar(tk.Scrollbar):
    def set(self, lo, hi):
        if float(lo) <= 0.0 and float(hi) >= 1.0:
            # grid_remove is currently missing from Tkinter!
            self.tk.call("grid", "remove", self)
        else:
            self.grid()
        tk.Scrollbar.set(self, lo, hi)

class Window(tk.Frame):

    def UserFileInput(self,status,name):
        row = self.row
        optionLabel = tk.Label(self)
        optionLabel.grid(row=row, column=0, sticky='w')
        optionLabel["text"] = name
        text = status#str(dirname) if dirname else status
        var = tk.StringVar(root)
        var.set(text)
        w = tk.Entry(self, textvariable= var)
        w.grid(row=row, column=1, sticky='ew')
        w.grid_columnconfigure(1,weight=1)
        self.row += 1
        return w, var

    def __init__(self,parent):
        tk.Frame.__init__(self,parent)

        self.row = 0
        currentDirectory = os.getcwd()
        directory,var = self.UserFileInput(currentDirectory, "Directory")


if __name__ == "__main__":
    root = tk.Tk()
    root.grid_columnconfigure(0, weight=1)
    root.grid_rowconfigure(0,weight=1)

    vscrollbar = AutoScrollbar(root,orient=tk.VERTICAL)
    vscrollbar.grid(row=0, column=1, sticky='ns')
    hscrollbar = AutoScrollbar(root, orient=tk.HORIZONTAL)
    hscrollbar.grid(row=1, column=0, sticky='ew')

    canvas=tk.Canvas(root,yscrollcommand=vscrollbar.set,xscrollcommand=hscrollbar.set)
    canvas.grid(row=0, column=0, sticky='nsew')
    vscrollbar.config(command=canvas.yview)
    hscrollbar.config(command=canvas.xview)


    window = Window(canvas)
    canvas.create_window(0, 0, anchor=tk.NW, window=window)
    window.update_idletasks()
    canvas.config(scrollregion=canvas.bbox("all"))

    root.mainloop()

You have several problems in your code that are getting in your way.您的代码中有几个问题阻碍了您的工作。 The biggest obstacle is that you're putting a frame inside a canvas.最大的障碍是您将框架放入画布中。 That's rarely necessary, and it makes your code more complex than it needs to be?这很少有必要,它会使您的代码比它需要的更复杂吗? Is there a reason you're using a canvas, and is there a reason you're using classes for part of your code but not for everything?您是否有理由使用画布,是否有理由将类用于部分代码而不是所有代码?

Regardless, you have two problems:无论如何,你有两个问题:

  1. the frame isn't growing when the window grows, so the contents inside the window can't grow当窗口增长时框架没有增长,所以窗口内的内容不能增长
  2. the label won't grow because you're using grid_columnconfigure incorrectly.标签不会增长,因为您使用grid_columnconfigure不正确。

Hints for visualizing the problem可视化问题的提示

When trying to solve layout problems, a really helpful technique is to temporarily give each containing widget a unique color so you can see where each widget is.在尝试解决布局问题时,一个非常有用的技术是暂时为每个包含的小部件指定唯一的颜色,以便您可以看到每个小部件的位置。 For example, coloring the canvas pink and the Window frame blue will make it clear that the Window frame is also not resizing.例如,将画布涂成粉红色,将Window框架涂成蓝色,可以清楚地表明Window框架也没有调整大小。

Resizing the frame调整框架大小

Because you're choosing to embed your widget in a canvas, you are going to have to manually adjust the width of the frame when the containing canvas changes size.因为您选择将小部件嵌入画布中,所以当包含的画布更改大小时,您将不得不手动调整框架的宽度。 You can do that by setting a binding on the canvas to call a function whenever it resizes.您可以通过在画布上设置绑定以在调整大小时调用函数来实现。 The event you use for this is <Configure> .您为此使用的事件是<Configure> Note: the configure binding fires for more than just size changes, but you can safely ignore that fact.注意:configure 绑定触发的不仅仅是大小更改,但您可以放心地忽略该事实。

The function needs to compute the width of the canvas, and thus the desired width of the frame (minus any padding you want).该函数需要计算画布的宽度,以及所需的框架宽度(减去您想要的任何填充)。 You'll then need to configure the frame to have that width.然后,您需要将框架配置为具有该宽度。 To facilitate that, you'll need to either keep a reference to the canvas id of the frame, or give the frame a unique tag.为方便起见,您需要保留对框架的画布 id 的引用,或者为框架提供唯一标签。

Here is a function that assumes the frame has the tag "frame":这是一个假设框架具有标签“框架”的函数:

def on_canvas_resize(event):
    padding = 8
    width = canvas.winfo_width() - padding
    canvas.itemconfigure("frame", width=width)

You'll need to adjust how you create the canvas item to include the tag:您需要调整创建画布项目的方式以包含标签:

canvas.create_window(..., tags=["frame"])

Finally, set a binding to fire when the widget changes size:最后,设置绑定以在小部件更改大小时触发:

canvas.bind("<Configure>", on_canvas_resize)

Using grid_columnconfigure to get the label to resize使用 grid_columnconfigure 获取要调整大小的标签

You need to use grid_columnconfigure on the containing widget.您需要在包含的小部件上使用grid_columnconfigure You want the columns inside the frame to grow and shrink, not the columns inside the label.您希望框架内的列增长和收缩,而不是标签内的列。

You need to change this line:您需要更改此行:

w.grid_columnconfigure(...)

to this:对此:

self.grid_columnconfigure(...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM