如何使Tkinter文本小部件只对某些字符和句子进行读取



上下文:我正试图在文本框外使用tkinter制作一个终端。终端的一个属性是,一旦您执行了一行代码(在点击回车后(,您将无法在前一行上进行编辑/键入内容,但您可以在新行上键入内容(在执行后(。您也将无法编辑给定的输出以及终端的起始参数。

示例:https://i.stack.imgur.com/Ptuok.png

我将无法编辑或在我圈出的字符和行中写入任何内容:https://i.stack.imgur.com/MMmQq.png.但我能够在字符"之后的新行中键入一些内容;C: \>quot;

问:那么我如何在文本框中使用tkinter来实现这一点呢?在我的情况下,我应该不能编辑/更改字符,";C: \>quot;以及以前的句子(包括输入和输出(

研究:我做了一些研究,你可以用";state=DISABLED";但它阻止您修改对整个文本框的更改

我现在的代码:

from tkinter import *
def enter(event):
def insert():
tfield.insert("end", ">>>")
root.after(10, insert)
root = Tk()
tfield = Text(root, bg='black', fg='white')
tfield.pack()
tfield.bind("<Return>", enter)
root.mainloop()

您可以使用标记来跟踪可编辑部分的开头,我称之为"输入";在下面的代码中。此外,我还改编了Bryan Oakley的答案https://stackoverflow.com/a/16375233/6415268:它不更新代理中的行号,而是检查可编辑部分中是否插入/删除了字符。为此,我使用:Text.compare('insert' < 'input')

下面是一个完整的例子:

import tkinter as tk
class ConsoleText(tk.Text):
def __init__(self, master=None, **kw):
tk.Text.__init__(self, master, **kw)
self.insert('1.0', '>>> ') # first prompt
# create input mark
self.mark_set('input', 'insert')
self.mark_gravity('input', 'left')
# create proxy
self._orig = self._w + "_orig"
self.tk.call("rename", self._w, self._orig)
self.tk.createcommand(self._w, self._proxy)
# binding to Enter key
self.bind("<Return>", self.enter)

def _proxy(self, *args):
largs = list(args)
if args[0] == 'insert':
if self.compare('insert', '<', 'input'):
# move insertion cursor to the editable part
self.mark_set('insert', 'end')  # you can change 'end' with 'input'
elif args[0] == "delete":
if self.compare(largs[1], '<', 'input'):
if len(largs) == 2:
return # don't delete anything
largs[1] = 'input'  # move deletion start at 'input'
result = self.tk.call((self._orig,) + tuple(largs))
return result
def enter(self, event):
command = self.get('input', 'end')
# execute code
print(command)
# display result and next promp
self.insert('end', 'nCommand resultnn>>> ')
# move input mark
self.mark_set('input', 'insert')
return "break" # don't execute class method that inserts a newline
root = tk.Tk()
tfield = ConsoleText(root, bg='black', fg='white', insertbackground='white')
tfield.pack()
root.mainloop()

最新更新