[英]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:无论如何,你有两个问题:
grid_columnconfigure
incorrectly.标签不会增长,因为您使用grid_columnconfigure
不正确。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
框架也没有调整大小。
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)
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.