Python tkinter 缩小小部件

Python tkinter downsizing widgets

我查看了所有其他问题和答案,但找不到适合我正在尝试做的事情的问题和答案。

代码:

class GameWin:
    def __init__(self, master):
        self.master = master
        self.master.title("Title")

        self.main_frame = Frame(self.master, bd = 10, bg = uni_bg)
        self.main_frame.grid()

        self.left_frame = Frame(self.main_frame, bd = 10, bg = uni_bg)
        self.left_frame.grid(column = 0, row = 0)

        self.right_frame = Frame(self.main_frame, bd = 10, bg = uni_bg)
        self.right_frame.grid(column = 1, row = 0)

        self.right_frame.columnconfigure(0, weight = 1)
        self.right_frame.rowconfigure(0, weight = 1)
        self.right_frame.columnconfigure(1, weight = 1)
        self.right_frame.rowconfigure(1, weight = 1)

        self.web = Text(self.left_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bt_bg, fg = uni_fg)
        self.web.grid(column = 0, row = 0, padx = 5, pady = 5)

        self.output = Text(self.left_frame, font = (uni_font, 12), wrap = WORD, bg = "black", fg = uni_fg)
        self.output.grid(column = 0, row = 1, padx = 5, pady = 5, sticky = "ew")
        self.output.configure(state = "disabled")

        self.input = Entry(self.left_frame, font = (uni_font, 12))
        self.input.grid(column = 0, row = 2, sticky = "ew")
        self.input.bind('<Return>', self.submit)

        self.notepad = Text(self.right_frame, font = (uni_font, 12), wrap = WORD, bg = uni_fg, fg = "black", width = 42)
        self.notepad.grid(column = 0, row = 0, pady = 5, rowspan = 2)

        self.sys_info = Text(self.right_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bg, fg = uni_fg, width = 35, height = 11, bd = 0)
        self.sys_info.tag_configure('center', justify='center')
        self.sys_info.grid(column = 1, row = 0, pady = 5)
        self.sys_info.insert(END, "NAME", "center")
        self.sys_info.configure(state = "disabled")

        self.trace = Text(self.right_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bg, fg = uni_fg, width = 35, height = 11)
        self.trace.grid(column = 1, row = 1, pady = 5)

        self.email = Text(self.right_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bt_bg, fg = uni_fg)
        self.email.grid(column = 0, row = 2, pady = 5, columnspan = 2)
        self.email.configure(state = "disabled")

        self.respond = Entry(self.right_frame, font = (uni_font, 12))
        self.respond.grid(column = 0, row = 3, columnspan = 2, sticky = "ew")
        self.respond.bind('<Return>', self.do_respond)

    def submit(self, event):
        self.output.configure(state = "normal")
        self.output.configure(state = "disabled")
        pass

    def do_respond(self, event):
        pass

当前屏幕图像:https://i.imgur.com/P2B6E5y.png

我想弄清楚的第一件事是如何不明确说明右上角的 3 个文本小部件的大小。因为每个人的屏幕大小不一样。如果我没有明确说明大小,它们就会展开,一切都会变得很奇怪(因为默认的文本小部件很大)。我希望小部件自动缩小以适合列(与大灰色右下角文本小部件的宽度相同)。这可能吗?

其次是框架和小部件填满 window 中的所有 space。无论是全屏(如图片所示)还是更小的 window(并希望保持它们的大小相对于彼此)。 window 的边缘有很多空的 space,我想去掉它。我已经尝试了所有我能想到的方法,但我无法让他们填写 space。

我尝试将前 3 个小部件分别放在自己的框架中,限制框架相对于 window 大小的大小,并设置小部件以填充该框架,但它不起作用。我曾经尝试过的代码:https://pastebin.com/3YWK9Xg2

class GameWin:
    def __init__(self, master):
        self.master = master
        self.master.title("Hacker")
        win_width = self.master.winfo_width()
        win_height = self.master.winfo_height()

        self.main_frame = Frame(self.master, bd = 10, bg = uni_bg)
        self.main_frame.grid(sticky = "nsew")

        self.left_frame = Frame(self.main_frame, bd = 10, bg = uni_bg, height = int(win_height), width = int(win_width/2))
        self.left_frame.grid(column = 0, row = 0, rowspan = 3)
        self.left_frame.grid_propagate(False)

        self.note_frame = Frame(self.main_frame, bd = 10, bg = uni_bg, height = int(win_height/2), width = int(win_width/4))
        self.note_frame.grid(column = 1, row = 0, rowspan = 2, sticky = "n")
        self.note_frame.grid_propagate(False)

        self.sys_frame = Frame(self.main_frame, bd = 10, bg = uni_bg, height = int(win_height/4), width = int(win_width/4))
        self.sys_frame.grid(column = 2, row = 0, sticky = "n")
        self.sys_frame.grid_propagate(False)

        self.trace_frame = Frame(self.main_frame, bd = 10, bg = uni_bg, height = int(win_height/4), width = int(win_width/4))
        self.trace_frame.grid(column = 2, row = 1, sticky = "n")
        self.trace_frame.grid_propagate(False)

        self.bottom_right_frame = Frame(self.main_frame, bd = 10, bg = uni_bg, height = int(win_height/2), width = int(win_width/2))
        self.bottom_right_frame.grid(column = 1, row = 2, columnspan = 2)
        self.bottom_right_frame.grid_propagate(False)

        self.web = Text(self.left_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bt_bg, fg = uni_fg)
        self.web.grid(column = 0, row = 0, padx = 5, pady = 5)

        self.output = Text(self.left_frame, font = (uni_font, 12), wrap = WORD, bg = "black", fg = uni_fg)
        self.output.grid(column = 0, row = 1, padx = 5, pady = 5, sticky = "ew")


        self.input = Entry(self.left_frame, font = (uni_font, 12))
        self.input.grid(column = 0, row = 2, sticky = "ew")
        self.input.bind('<Return>', self.submit)

        self.notepad = Text(self.note_frame, font = (uni_font, 12), wrap = WORD, bg = uni_fg, fg = "black")
        self.notepad.pack(fill = BOTH, expand = YES)

        self.sys_info = Text(self.sys_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bg, fg = uni_fg)
        self.sys_info.tag_configure('center', justify='center')
        self.sys_info.grid(sticky = "nsew")
        self.sys_info.insert(END, "NAME", "center")
        self.sys_info.configure(state = "disabled")

        self.trace = Text(self.trace_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bg, fg = uni_fg)
        self.trace.grid(sticky = "nsew")

        self.email = Text(self.bottom_right_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bt_bg, fg = uni_fg)
        self.email.grid(row = 0, pady = 5, columnspan = 2, sticky = "nsew")
        self.email.configure(state = "disabled")

        self.respond = Entry(self.bottom_right_frame, font = (uni_font, 12))
        self.respond.grid(row = 1, columnspan = 2, sticky = "ew")
        self.respond.bind('<Return>', self.do_respond)

    def submit(self, event):
        self.output.configure(state = "normal")
        self.output.configure(state = "disabled")

    def do_respond(self, event):
        pass

结果图片:https://i.imgur.com/IVnw65x.png

完整代码如下:https://pastebin.com/Gm2ePqFH。我希望它看起来像第一张图片中的那样,而不必明确说明每个文本小部件的大小。我想让它相对于 window.

保持相同的大小

如果您希望小部件缩小到列的大小,对我来说最有效的策略是使小部件非常小,然后使用布局管理器(packplace, 或 grid) 使它们变大以适合。如果确实是您可以接受的最小尺寸,您可以将小部件设为 1x1,或者您可以将其设置为您认为绝对最小值应该是什么(例如,4 行 20 个字符,20 行 10 个字符,等等)。

因此,首先让这些小部件尽可能小。

接下来,确保使用 sticky 属性,以便小部件增长以填充其分配的 space。您还需要确保为 self.right_frame 使用 sticky 属性,以便它也填充其 space。

最后,请确保您调用 rowconfigurecolumnconfigure 为任何具有由 grid 管理的子项的小部件设置正权重。您不会为 self.master 这样做,也不会为 self.left_frameself.right_frame

这样做

根据经验,如果您只将一个或两个小部件放在一个框架中并且您希望这些小部件填充框架,那么使用 packgrid 好得多,仅仅是因为您不必记住为行和列赋予权重。

例如,您可以使用pack来管理左右框架。您也可以使用 packGameWin 放入其母版中。

此外,不要试图一次性解决所有布局问题。对于您的情况,我会这样解决问题:

  • 从您的 mainframe 开始并获取它,以便它填充包含 window。确保手动调整 window 的大小以观察它的增大和缩小。

  • 接下来,添加左右框架。确保它们变大和变小以适应 mainframe.

  • 接下来,只关注左侧框架中的小部件。添加它们,并确保它们收缩并适合。

  • 然后,关注右框。添加它们,并确保它们缩小并适合。

最后,提个忠告。将您对 grid 的通话分组在一起。现在编写代码时,您需要修复散布在整个文件中的一大堆行。通过一些重组,几乎所有需要更改的代码行都将在一个代码块中。

例如,而不是这个:

self.web = Text(...)
self.web.grid(...)
self.output = Text(...)
self.output.grid(...)
self.input = Text(...)
self.input.grid(...)
self.notepad = Text(...)
self.notepad.grid(...)

这样做:

self.web = Text(...)
self.output = Text(...)
self.input = Text(...)
self.notepad = Text(...)

self.web.grid(...)
self.output.grid(...)
self.input.grid(...)
self.notepad.grid(...)

这样一来就可以回答"how are my widgets defined?"和"how are my widgets laid out"的问题了。以你现在的方式,这些问题很难回答。