【问题标题】:Resize entry box in tkinter在 tkinter 中调整输入框的大小
【发布时间】:2014-08-14 14:22:51
【问题描述】:

以下 MWE 适用于具有水平和垂直滚动条的窗口。该窗口包含一个显示当前工作目录的输入框。但是,由于框太小,无法全部看到输入框中的文本。当用户放大窗口时,我希望能够显示更多此文本。如何调整以下示例,以便输入框(在 UserFileInput 中定义)随窗口调整大小?我试过使用window.grid_columnconfigure(见下文),但这没有任何效果。使用画布似乎是一个问题,因为以前我能够调整输入框的大小,但是我需要画布才能在窗口上放置水平和垂直滚动条。

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

(还有 column = 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()

【问题讨论】:

    标签: python user-interface tkinter


    【解决方案1】:

    您的代码中有几个问题阻碍了您的工作。最大的障碍是您在画布内放置了一个框架。这很少需要,并且它使您的代码比它需要的更复杂?您使用画布是否有原因,您是否有原因将类用于部分代码而不是所有代码?

    不管怎样,你有两个问题:

    1. 窗口增长时框架没有增长,所以窗口内的内容也不能增长
    2. 标签不会增长,因为您错误地使用了grid_columnconfigure

    可视化问题的提示

    在尝试解决布局问题时,一个非常有用的技术是临时为每个包含的小部件赋予唯一的颜色,这样您就可以看到每个小部件的位置。例如,将画布涂成粉红色并将Window 框架涂成蓝色,可以清楚地看出Window 框架也没有调整大小。

    调整框架大小

    因为您选择将小部件嵌入到画布中,所以当包含的画布改变大小时,您将不得不手动调整框架的宽度。您可以通过在画布上设置绑定以在调整大小时调用函数来做到这一点。您为此使用的事件是&lt;Configure&gt;。注意:配置绑定触发的不仅仅是大小更改,但您可以放心地忽略这一事实。

    该函数需要计算画布的宽度,因此需要计算框架的宽度(减去您想要的任何填充)。然后,您需要将框架配置为具有该宽度。为方便起见,您需要保留对框架的画布 ID 的引用,或者给框架一个唯一的标签。

    这是一个假设框架具有标签“框架”的函数:

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

    您需要调整创建画布项目的方式以包含标签:

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

    最后,设置一个在小部件改变大小时触发的绑定:

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

    使用 grid_columnconfigure 获取要调整大小的标签

    您需要在 包含 小部件上使用grid_columnconfigure。您希望框架内的列增长和缩小,而不是标签内的列。

    你需要改变这一行:

    w.grid_columnconfigure(...)
    

    到这里:

    self.grid_columnconfigure(...)
    

    【讨论】:

    • 最初我没有使用画布,只是一个框架。但是,我的窗口比我的屏幕大,并且我在窗口底部丢失了文本,因此我想添加一个滚动条以便可以查看所有文本。阅读它似乎只有在画布上才有可能,我使用了这个例子effbot.org/zone/tkinter-autoscrollbar.htm。如果有更简单的方法,我会很乐意使用它。我不知道你说的类是什么意思。我不知道我还能在课堂上放什么。
    • @Mark:程序末尾有 15 行代码,它们不是一个类。有关如何为应用程序使用类的示例,请参见此处:stackoverflow.com/a/17470842/7432
    • 理论上我理解你的答案,但实际上我无法让它发挥作用。我对 tkinter 很陌生,所以还有很多我不明白的地方。我已将我的新代码作为另一个问题发布 - stackoverflow.com/questions/25317208/resize-widget-in-canvas 。也许你可以告诉我我现在哪里出错了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多