我在Mac OS X 10.11.5上使用tcl / tk 8.5.9和python 3.5.1处理gui。
我试图创建一种tk.text小部件列表,这些小部件具有固定的宽度并调整高度以适应其内容(无论是用户还是以编程方式)。这应该考虑到真实和包裹的排便。
我使用Tkinter Resize text to contents和here的答案让这个工作。但是,调整为用户输入仅适用于最后创建的文本窗口小部件。一旦添加了新的文本窗口小部件,所有以前创建的文本窗口小部件都不会再调整大小。
我认为问题可能出在处理bindtags的行中。作为tkinter,python的新手,一般来说编程相对较新,我不确定我是否正确理解了绑定标记。
非常感谢任何帮助,这是我的代码:
from tkinter import *
class ResizingText(Text):
def __init__(self, parent, *args, **kwargs):
Text.__init__(self, master=parent, wrap='word', *args, **kwargs)
# event binding on resize because text.count method for displaylines returns a wrong number when widget is instantiated
self.bind('<Configure>', self.update_size)
bindtags = list(self.bindtags())
bindtags.insert(2, "custom")
self.bindtags(tuple(bindtags))
self.bind_class("custom", "<Key>", self.update_size)
def update_size(self, event):
if self.winfo_width() > 1:
self.unbind('<Configure>')
displaylines = self.count("1.0", "end", "displaylines")
self.config(height=displaylines)
root = Tk()
dynamic_text_1 = ResizingText(root, width=60)
dynamic_text_1.insert('1.0', "Longer text that is long enough to be wrapped into multiple display lines")
dynamic_text_1.grid(column=0, row=0)
# this text widget does not behave as expected:
# no resizing after user inputs a line break or a line long enough to be wrapped
dynamic_text_2 = ResizingText(root, width=60)
dynamic_text_2.insert('1.0', "Longer text that is long enough to be wrapped into multiple display lines")
dynamic_text_2.grid(column=0, row=1)
# this text widget behaves as expected
root.mainloop()
答案 0 :(得分:1)
我通过配置bindtags并在每次文本小部件获得焦点时重置事件绑定来解决这个问题(在FocusIn上绑定事件)。
可能不是一个干净的解决方案,但似乎工作正常:
from tkinter import *
class ResizingText(Text):
def __init__(self, parent, *args, **kwargs):
Text.__init__(self, master=parent, wrap='word', *args, **kwargs)
# event binding on resize because text.count method for displaylines returns a wrong number when widget is instantiated
self.bind('<Configure>', self.update_size)
self.configure_bindtags(event=None)
# solution: additional binding that resets the binding for <Key> events whenever the text widget gets the focus
self.bind('<FocusIn>', self.configure_bindtags)
def configure_bindtags(self, event):
bindtags = list(self.bindtags())
bindtags.insert(2, "custom")
self.bindtags(tuple(bindtags))
self.bind_class("custom", "<Key>", self.update_size)
def update_size(self, event):
if self.winfo_width() > 1:
self.unbind('<Configure>')
displaylines = self.count("1.0", "end", "displaylines")
self.config(height=displaylines)
root = Tk()
dynamic_text_1 = ResizingText(root, width=60)
dynamic_text_1.insert('1.0', "Longer text that is long enough to be wrapped into multiple display lines")
dynamic_text_1.grid(column=0, row=0)
dynamic_text_2 = ResizingText(root, width=60)
dynamic_text_2.insert('1.0', "Longer text that is long enough to be wrapped into multiple display lines")
dynamic_text_2.grid(column=0, row=1)
root.mainloop()