python - Tkinter 文本小部件比任何其他带有网格的小部件更宽

标签 python python-3.x tkinter listbox

从教程中,我有一种印象,网格只是“计算出”宽度,但当涉及到文本时,情况显然并非如此(我想当与列表结合时)。

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

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

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

无论如何,使用下面的代码 - 谁能向我解释如何使这些宽度更合理,并且也相同?我应该将宽度硬编码为文本,然后将列表框设置为 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 完全不同(甚至当我指定一个宽度)。

最佳答案

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

  1. 您没有设置 self.lst_bx 的宽度,因此 tkinter 默认将其设置为 20 个字符。

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

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

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

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 个宽度尺寸。

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

enter image description here

关于python - Tkinter 文本小部件比任何其他带有网格的小部件更宽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47300073/

相关文章:

python redis 客户端无法使用.hgetall(key) 获取现有哈希值

python - 更多 pythonic 方法来做到这一点(字符串拆分)?

python - 在 Python3 中使用 for 循环为 vigenere 密码创建 2D 列表

python-3.x - Pandas 基于 groupby 创建百分位字段,级别为 1

python - Tkinter 按钮与网格对齐

python - 检测用户是否点击了 'maximized'按钮

python - 如何强制 NumPy 将列表附加为对象?

python - 如何使用经过训练的 skipgram 模型预测单词?

python - 在 Python3.6.1 中调用 loop.close asyncio.get_event_loop 后无法创建新的事件循环

image - 使用 Tkinter 在标签图像上叠加一个框