【问题标题】:Tkinter text widget is wider than any other widget with gridTkinter 文本小部件比任何其他带有网格的小部件都宽
【发布时间】:2018-04-28 05:53:00
【问题描述】:

从教程中,我有一种印象,即网格只是“计算出来”的宽度,但对于文本显然不是这种情况(我想与列表结合使用时)。

使用以下代码,列表框很小,而文本绝对很大(宽度方面)。我可以通过更改sticky="ew" 使列表框等于文本的大小,但这不是我想要的——我想要一个合理的、等效样式的“网格”。

如果我硬编码宽度的大小,那就更令人沮丧了,因为列表框的宽度似乎等于文本宽度的大约 2/3。

我已经阅读了 rowconfigure 和 columnconfigure,但这似乎对下面的代码没有任何作用(注意 - rowconfigure 和 columnconfigure 不在下面的代码中,但我已经尝试过了,也许我用错了)。

无论如何,使用下面的代码 - 任何人都可以向我解释如何使这些尺寸更合理,宽度也一样吗?我是否应该将宽度硬编码为 Text,然后将列表框设置为 Sticky="ew"?似乎与网格布局概念背道而驰。

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        self.frame = tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        self.initialize()

    def initialize(self):

        self.lst_bx = tk.Listbox(self.parent, height = 15)
        self.lst_bx.grid(row=0, column=0, columnspan=2, padx=(10,10), sticky="w")

        self.exe_field = tk.Text(self.parent, height=15)
        self.exe_field.grid(row=1, column=0, columnspan=2, padx=(10,10), sticky="w")

        self.pick_exe_btn = tk.Button(
            self.parent, text="Choose Location", width=15
        )
        self.pick_exe_btn.grid(row=0, column=2)



if __name__ == "__main__":
    root = tk.Tk()
    #window_config(root)
    MainApplication(root).grid(stick="nesw")
    root.resizable(False, False)
    root.mainloop()

我很抱歉我是个菜鸟,我发誓我在这里发帖之前已经搜索了很多 - 我只是找不到关于为什么 ListBox 与 Text 的宽度完全不同的直接答案(当我指定一个时更是如此宽度)。

【问题讨论】:

  • 为了获得一个合理的、等效样式的“网格”,创建框架并将小部件放在框架内。正确使用rowspancolumnspan 和`粘性参数。这需要一些时间,复杂性取决于您尝试实现的 UI 类型。
  • @Abhijeetk431 你有如何做到这一点的例子吗?
  • 顺便说一句:首先:__init__ 总是返回 None,所以分配给 self.frame 是没有意义的——你可以使用 self 来访问这个框架。第二:self.parent 保留root,因此您将小部件直接放在root 中,而不是在框架MainApplication 中。使用self 将小部件放入框架MainApplication。第三:ListboxText 可以使用不同的字体,tkinter 使用width= 和字体大小计算实际宽度。
  • 我认为你想要的不清楚,文本小部件似乎是默认大小。如果你想减小它的宽度,那么配置width?
  • 也许提供一张您希望 GUI 看起来像的图像。

标签: python python-3.x tkinter listbox


【解决方案1】:

tkinter 如何计算尺寸 tkinter.ListBox() 和 tkinter.Text() 小部件与大多数其他使用像素的小部件略有不同。对于这两个特定的小部件,宽度是根据字符计算的,而高度是根据行来评估的。

  1. 你没有设置self.lst_bx的宽度,所以tkinter默认设置为20个字符。

  2. 您也没有指定self.exe_field 的宽度。所以 tkinter 根据当前默认字体大小计算这个宽度。

从 1) 和 2) 我们可以得出结论,我们不能期望 self.exe_fieldself.lst_bx 具有相同的宽度是很正常的。这意味着,除了对它们进行硬编码和直观地检查 GUI 之外,您别无选择。

通过对您的代码进行细微更改(主要在您的问题下方的 cmets 中提供),这就是我解决您的问题的方法:

import tkinter as tk


class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.lst_bx = tk.Listbox(self, height = 15, width=70)
        self.lst_bx.grid(row=0, column=0, padx=(10,10), sticky="w")

        self.exe_field = tk.Text(self, height=15, width=80)
        self.exe_field.grid(row=1, column=0, padx=(10,10), sticky="w")

        self.pick_exe_btn = tk.Button(self, text="Choose Location", width=15)
        self.pick_exe_btn.grid(row=0, column=2, columnspan=2)


if __name__ == "__main__":
    root = tk.Tk()
    #window_config(root)
    MainApplication(root).grid(stick="nesw")
    root.resizable(False, False)
    root.mainloop()

注意我将columnspace 选项移到了哪里(它在您之前设置的两个地方完全没有意义)。另请注意,tkinter 在列表框和文本小部件之间以某种方式计算字符。根据您的操作系统(也可能是机器),您可能需要更改我为相关小部件设置的 2 个宽度尺寸。

这是我在我的机器上得到的:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多