绑定事件在键入的字符被放入条目之前运行
Bind event runs before character typed is put in entry
我正在用 tkinter 制作一个特殊的文本小部件,它应该有工作缩进。为了使缩进起作用,我将放下制表符的功能绑定到 Enter 按钮。此绑定在实际键入的字符之后进行绑定之前工作正常,但不适用于此功能。有人可以帮我吗?
工作绑定:
def double_parentheses(self, event):
main_text_box_anchor = str(self.text.index("insert")).split(".")
self.text.insert(INSERT, ")")
self.text.mark_set(INSERT, str(main_text_box_anchor[0]) + "." +
str(int(main_text_box_anchor[1])))
#later in the code
scroll.text.bind("(", scroll.double_parentheses)
这会将括号按顺序排列,并在中间插入
不工作:
def new_line_indent(self, event):
line = self.text.get("insert linestart", "insert lineend")
editable_line = str(line)
if editable_line != "":
if editable_line[-1] == ":":
if "\t" in editable_line:
for i in range(editable_line.count("\t")):
self.text.insert("insert", "\t")
else:
self.text.insert("insert", "\t")
elif "\t" in editable_line:
for i in range(editable_line.count("\t")):
self.text.insert("insert", "\t")
#Later in the code
scroll.text.bind("<Return>", scroll.new_line_indent)
这会放入制表符,但它是在创建新行之前完成的,我不明白为什么。我做错了什么?
This puts the tabs in but it does it BEFORE the new line is created and I can't figure out why.
简短的回答是您的绑定发生在 built-in 键绑定之前。因此,您的函数在 tkinter 实际插入换行符之前被调用。
您应该让代码插入换行符,执行其他操作,然后 return“中断”以防止发生默认行为。
有关如何处理绑定的更详尽的解释,请参阅this answer
这是一个工作示例:
def new_line_indent(self, event):
# get the text of the current line
line = self.text.get("insert linestart", "insert lineend")
# insert the newline
self.text.insert("insert", "\n")
# insert indentation if line ends with ":"
if line and line[-1] == ":":
# get current indentation, then insert it
leading_whitespace = self.get_leading_whitespace(line)
self.text.insert("insert", leading_whitespace)
# add an additional level of indentation
self.text.insert("insert", "\t")
# since we already inserted the newline, make sure that
# the default bindings do not
return "break"
def get_leading_whitespace(self, line):
n = len(line) - len(line.lstrip())
return line[:n]
除了 Bryan 建议的解决方案之外,您可以绑定 <KeyRelease-Return>
而不是 <Return>
。然后回调会在添加换行符后执行:
def new_line_indent(self, event):
# get previous line
line = self.text.get("insert-1c linestart", "insert-1c lineend")
editable_line = str(line)
if editable_line != "":
for i in range(editable_line.count("\t")):
self.text.insert("insert", "\t")
if editable_line[-1] == ":":
self.text.insert("insert", "\t")
...
#Later in the code
scroll.text.bind("<KeyRelease-Return>", scroll.new_line_indent)
我正在用 tkinter 制作一个特殊的文本小部件,它应该有工作缩进。为了使缩进起作用,我将放下制表符的功能绑定到 Enter 按钮。此绑定在实际键入的字符之后进行绑定之前工作正常,但不适用于此功能。有人可以帮我吗?
工作绑定:
def double_parentheses(self, event):
main_text_box_anchor = str(self.text.index("insert")).split(".")
self.text.insert(INSERT, ")")
self.text.mark_set(INSERT, str(main_text_box_anchor[0]) + "." +
str(int(main_text_box_anchor[1])))
#later in the code
scroll.text.bind("(", scroll.double_parentheses)
这会将括号按顺序排列,并在中间插入
不工作:
def new_line_indent(self, event):
line = self.text.get("insert linestart", "insert lineend")
editable_line = str(line)
if editable_line != "":
if editable_line[-1] == ":":
if "\t" in editable_line:
for i in range(editable_line.count("\t")):
self.text.insert("insert", "\t")
else:
self.text.insert("insert", "\t")
elif "\t" in editable_line:
for i in range(editable_line.count("\t")):
self.text.insert("insert", "\t")
#Later in the code
scroll.text.bind("<Return>", scroll.new_line_indent)
这会放入制表符,但它是在创建新行之前完成的,我不明白为什么。我做错了什么?
This puts the tabs in but it does it BEFORE the new line is created and I can't figure out why.
简短的回答是您的绑定发生在 built-in 键绑定之前。因此,您的函数在 tkinter 实际插入换行符之前被调用。
您应该让代码插入换行符,执行其他操作,然后 return“中断”以防止发生默认行为。
有关如何处理绑定的更详尽的解释,请参阅this answer
这是一个工作示例:
def new_line_indent(self, event):
# get the text of the current line
line = self.text.get("insert linestart", "insert lineend")
# insert the newline
self.text.insert("insert", "\n")
# insert indentation if line ends with ":"
if line and line[-1] == ":":
# get current indentation, then insert it
leading_whitespace = self.get_leading_whitespace(line)
self.text.insert("insert", leading_whitespace)
# add an additional level of indentation
self.text.insert("insert", "\t")
# since we already inserted the newline, make sure that
# the default bindings do not
return "break"
def get_leading_whitespace(self, line):
n = len(line) - len(line.lstrip())
return line[:n]
除了 Bryan 建议的解决方案之外,您可以绑定 <KeyRelease-Return>
而不是 <Return>
。然后回调会在添加换行符后执行:
def new_line_indent(self, event):
# get previous line
line = self.text.get("insert-1c linestart", "insert-1c lineend")
editable_line = str(line)
if editable_line != "":
for i in range(editable_line.count("\t")):
self.text.insert("insert", "\t")
if editable_line[-1] == ":":
self.text.insert("insert", "\t")
...
#Later in the code
scroll.text.bind("<KeyRelease-Return>", scroll.new_line_indent)