Tkinter:在Text小部件中使用Checkbutton和Scrollbar

2 投票
2 回答
3264 浏览
提问于 2025-04-17 16:20

我创建了两个文本框,放在一起。左边的文本框里有100行复选框,右边的文本框里有100行文字。我把这两个文本框的高度和宽度都设置成了30和10。

当我运行程序时,左边的文本框垂直方向上超出了我能看到的屏幕范围。结果,右边的文本框被推得很低,我看不到它了。我知道它在那儿,因为当我把两个文本框的行数都减少到50时,我就能看到右边的文本框了。

另外,我还注意到左边的滚动条没有和左边的文本框连接起来,而右边的滚动条则正确地连接到了右边的文本框。

你能帮我理解一下吗:

1) 为什么左边的文本框会在垂直方向上增长(超出了定义的文本框大小),而且和右边的文本框的大小和位置不同步?

2) 为什么左边的滚动条没有连接到左边的文本框(就像右边的文本框那样)?

这是我目前的代码:

#!/usr/bin/python
from Tkinter import *

class MyApp:
    def __init__(self, parent):
       self.myParent = parent
       self.main_container = Frame(self.myParent)
       self.main_container.grid(row=0, column=0, columnspan=4)

       self.left_frame = Frame(self.main_container)
       self.left_frame.grid(row=0, column=0, columnspan=2)

       self.right_frame = Frame(self.main_container)
       self.right_frame.grid(row=0, column=2, columnspan=2)

       self.checkbox_scrollbar = Scrollbar(self.left_frame)
       self.checkbox_scrollbar.grid(row=0, column=1, sticky='NS')
       self.checkbox_text = Text(self.left_frame, height=30, width=10, yscrollcommand=self.checkbox_scrollbar.set)
       self.checkbox_text.grid(row=0, column=0)
       self.checkbox_scrollbar.config(command=self.checkbox_text.yview)

       self.databox_scrollbar = Scrollbar(self.right_frame)
       self.databox_scrollbar.grid(row=0, column=1, sticky='NS')
       self.databox_text = Text(self.right_frame, height=30, width=10, yscrollcommand=self.databox_scrollbar.set)
       self.databox_text.grid(row=0, column=0)
       self.databox_scrollbar.config(command=self.databox_text.yview)

    my_dict = {}
    for each_num in range(100):
        my_line = "Line number: " + str(each_num)
        my_dict[my_line] = 0

    for my_key in my_dict:
        my_dict[my_key] = IntVar()
        cb = Checkbutton(self.checkbox_text, text=my_key, variable=my_dict[my_key])
        cb.grid(sticky='W')

    for each_entry in range(100):
        entry_line = "This is entry number: " + str(each_entry) + "\n"
        self.databox_text.insert(END, entry_line)


root = Tk()
root.title("Checkbox UI Test")
myapp = MyApp(root)
root.mainloop()

2 个回答

1

我花了一个小时在这个问题上,但我的Tkinter知识还不够全面,所以我相信会有人给出其他答案。不过,我想说的是:

从我能看出来,Text框其实没有显示出来,因为它被后面的CheckBox给遮住了。你可以试试在checkbox_text里插入一些文本,比如用checkbox_text.insert(END, "some text"),然后把背景改成"red",你会发现它在屏幕上是看不见的,即使你把100个复选框改成只显示2个。我不太明白为什么Text的高度限制没有被遵守,但我觉得CheckBox的布局可能和这个有关系。

同样的问题也影响到了ScrollBar,它是连接在左边的Frame上,而不是Text上;我还没试过,但也许在创建你想要连接的Text之后再创建ScrollBar会有帮助。

你提到的不同步的问题可能和设置weight有关,就像这个说的那样,但对我来说并没有效果。我觉得可能的原因是它们不在同一个网格里,所以它们无法互相传递大小信息。两个Frames的大小是一样的,我觉得这就是它们能做到的最好效果。

现在很晚了,我可能说错了什么,所以请对这些内容保持一点怀疑态度。

如果我遇到问题,我喜欢在相关的控件上用.config(bg="RED")来调试,有时候这能帮助我更清楚地看到发生了什么。

1

我需要用到Text组件的一个方法,叫做window_create,来插入我的嵌入对象(我的复选框组件)。下面是如何实现它的步骤。希望这能帮助到其他人:

for my_key in my_dict:
    my_dict[my_key] = IntVar()
    cb = Checkbutton(text=my_key, variable=my_dict[my_key])
    self.checkbox_text.window_create("END", window=cb)
    self.checkbox_text.insert("END", "\n")

撰写回答