Python 如何从 Tkinter Text Widget 获取输入?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14824163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:33:14  来源:igfitidea点击:

How to get the input from the Tkinter Text Widget?

pythontkinter

提问by xxmbabanexx

How to get Tkinter input from the Textwidget?

如何从小Text部件获取 Tkinter 输入?

EDIT

编辑

I asked this question to help others with the same problem - thatis the reason why there is no example code. This issue had been troubling me for hours and I used this question to teach others. Pleasedo not rate it as if it was a real question - the answer is the thing that matters.

我问这个问题是为了帮助遇到同样问题的其他人 -就是没有示例代码的原因。这个问题困扰了我好几个小时,我用这个问题来教别人。不要把它当作一个真正的问题来评价——答案才是最重要的。

采纳答案by xxmbabanexx

To get Tkinter input from the text box, you must add a few more attributes to the normal .get()function. If we have a text box myText_Box, then this is the method for retrieving its input.

要从文本框中获取 Tkinter 输入,您必须向普通.get()函数添加更多属性。如果我们有一个文本框myText_Box,那么这就是检索其输入的方法。

def retrieve_input():
    input = self.myText_Box.get("1.0",END)

The first part, "1.0"means that the input should be read from line one, character zero (ie: the very first character). ENDis an imported constant which is set to the string "end". The ENDpart means to read until the end of the text box is reached. The only issue with this is that it actually adds a newline to our input. So, in order to fix it we should change ENDto end-1c(Thanks Bryan Oakley) The -1cdeletes 1 character, while -2cwould mean delete two characters, and so on.

第一部分,"1.0"意味着输入应该从第一行读取,字符零(即:第一个字符)。END是设置为字符串的导入常量"end"。该END部分意味着阅读直到到达文本框的末尾。唯一的问题是它实际上为我们的输入添加了一个换行符。因此,为了修复它,我们应该更改ENDend-1c(感谢Bryan Oakley-1c删除 1 个字符,而-2c这意味着删除两个字符,依此类推。

def retrieve_input():
    input = self.myText_Box.get("1.0",'end-1c')

回答by Abdul Wahid

To get Tkinter input from the text box in python 3 the complete student level program used by me is as under:

要从 python 3 的文本框中获取 Tkinter 输入,我使用的完整学生级程序如下:

#Imports all (*) classes,
#atributes, and methods of tkinter into the
#current workspace

from tkinter import *

#***********************************
#Creates an instance of the class tkinter.Tk.
#This creates what is called the "root" window. By conventon,
#the root window in Tkinter is usually called "root",
#but you are free to call it by any other name.

root = Tk()
root.title('how to get text from textbox')


#**********************************
mystring = StringVar()

####define the function that the signup button will do
def getvalue():
##    print(mystring.get())
#*************************************

Label(root, text="Text to get").grid(row=0, sticky=W)  #label
Entry(root, textvariable = mystring).grid(row=0, column=1, sticky=E) #entry textbox

WSignUp = Button(root, text="print text", command=getvalue).grid(row=3, column=0, sticky=W) #button


############################################
# executes the mainloop (that is, the event loop) method of the root
# object. The mainloop method is what keeps the root window visible.
# If you remove the line, the window created will disappear
# immediately as the script stops running. This will happen so fast
# that you will not even see the window appearing on your screen.
# Keeping the mainloop running also lets you keep the
# program running until you press the close buton
root.mainloop()

回答by Skarga

Here is how I did it with python 3.5.2:

这是我用 python 3.5.2 做的:

from tkinter import *
root=Tk()
def retrieve_input():
    inputValue=textBox.get("1.0","end-1c")
    print(inputValue)

textBox=Text(root, height=2, width=10)
textBox.pack()
buttonCommit=Button(root, height=1, width=10, text="Commit", 
                    command=lambda: retrieve_input())
#command=lambda: retrieve_input() >>> just means do this when i press the button
buttonCommit.pack()

mainloop()

with that, when i typed "blah blah" in the text widget and pressed the button, whatever i typed got printed out. So i think that is the answer for storing user input from Text widget to variable.

有了这个,当我在文本小部件中输入“blah blah”并按下按钮时,我输入的任何内容都会被打印出来。所以我认为这是将用户输入从 Text 小部件存储到变量的答案。

回答by Nae

In order to obtain the string in a Textwidget one can simply use getmethod defined for Textwhich accepts 1 to 2 arguments as startand endpositions of characters, text_widget_object.get(start, end=None). If only startis passed and endisn't passed it returns only the single character positioned at start, if endispassed as well, it returns all characters in between positions startand endas string.

为了获取Text小部件中的字符串,可以简单地使用get定义的方法,Text该方法接受 1 到 2 个参数 asstartend字符位置,text_widget_object.get(start, end=None)。如果只start传递和end未传递,则仅返回位于 的单个字符start,如果end传递,则返回位置之间的所有字符startend作为字符串返回。

There are also special strings, that are variablesto the underlying Tk. One of them would be "end"or tk.ENDwhich represents the variable position of the very last char in the Textwidget. An example would be to returning all text in the widget, with text_widget_object.get('1.0', 'end')or text_widget_object.get('1.0', 'end-1c')if you don't want the last newline character.

还有一些特殊的字符串,它们是底层 Tk 的变量。其中之一是"end"ortk.END代表Text小部件中最后一个字符的可变位置。一个例子是返回小部件中的所有文本,text_widget_object.get('1.0', 'end')或者text_widget_object.get('1.0', 'end-1c')如果您不想要最后一个换行符。

Demo

演示

See below demonstration that selectsthe characters in between the given positions with sliders:

请参阅以下演示,使用滑块选择给定位置之间的字符:

try:
    import tkinter as tk
except:
    import Tkinter as tk


class Demo(tk.LabelFrame):
    """
    A LabeFrame that in order to demonstrate the string returned by the
    get method of Text widget, selects the characters in between the
    given arguments that are set with Scales.
    """

    def __init__(self, master, *args, **kwargs):
        tk.LabelFrame.__init__(self, master, *args, **kwargs)
        self.start_arg = ''
        self.end_arg = None
        self.position_frames = dict()
        self._create_widgets()
        self._layout()
        self.update()


    def _create_widgets(self):
        self._is_two_args = tk.Checkbutton(self,
                                    text="Use 2 positional arguments...")
        self.position_frames['start'] = PositionFrame(self,
                                    text="start='{}.{}'.format(line, column)")
        self.position_frames['end'] = PositionFrame(   self,
                                    text="end='{}.{}'.format(line, column)")
        self.text = TextWithStats(self, wrap='none')
        self._widget_configs()


    def _widget_configs(self):
        self.text.update_callback = self.update
        self._is_two_args.var = tk.BooleanVar(self, value=False)
        self._is_two_args.config(variable=self._is_two_args.var,
                                    onvalue=True, offvalue=False)
        self._is_two_args['command'] = self._is_two_args_handle
        for _key in self.position_frames:
            self.position_frames[_key].line.slider['command'] = self.update
            self.position_frames[_key].column.slider['command'] = self.update


    def _layout(self):
        self._is_two_args.grid(sticky='nsw', row=0, column=1)
        self.position_frames['start'].grid(sticky='nsew', row=1, column=0)
        #self.position_frames['end'].grid(sticky='nsew', row=1, column=1)
        self.text.grid(sticky='nsew', row=2, column=0,
                                                    rowspan=2, columnspan=2)
        _grid_size = self.grid_size()
        for _col in range(_grid_size[0]):
            self.grid_columnconfigure(_col, weight=1)
        for _row in range(_grid_size[1] - 1):
            self.grid_rowconfigure(_row + 1, weight=1)


    def _is_two_args_handle(self):
        self.update_arguments()
        if self._is_two_args.var.get():
            self.position_frames['end'].grid(sticky='nsew', row=1, column=1)
        else:
            self.position_frames['end'].grid_remove()


    def update(self, event=None):
        """
        Updates slider limits, argument values, labels representing the
        get method call.
        """

        self.update_sliders()
        self.update_arguments()


    def update_sliders(self):
        """
        Updates slider limits based on what's written in the text and
        which line is selected.
        """

        self._update_line_sliders()
        self._update_column_sliders()


    def _update_line_sliders(self):
        if self.text.lines_length:
            for _key in self.position_frames:
                self.position_frames[_key].line.slider['state'] = 'normal'
                self.position_frames[_key].line.slider['from_'] = 1
                _no_of_lines = self.text.line_count
                self.position_frames[_key].line.slider['to'] = _no_of_lines
        else:
            for _key in self.position_frames:
                self.position_frames[_key].line.slider['state'] = 'disabled'


    def _update_column_sliders(self):
        if self.text.lines_length:
            for _key in self.position_frames:
                self.position_frames[_key].column.slider['state'] = 'normal'
                self.position_frames[_key].column.slider['from_'] = 0
                _line_no = int(self.position_frames[_key].line.slider.get())-1
                _max_line_len = self.text.lines_length[_line_no]
                self.position_frames[_key].column.slider['to'] = _max_line_len
        else:
            for _key in self.position_frames:
                self.position_frames[_key].column.slider['state'] = 'disabled'


    def update_arguments(self):
        """
        Updates the values representing the arguments passed to the get
        method, based on whether or not the 2nd positional argument is
        active and the slider positions.
        """

        _start_line_no = self.position_frames['start'].line.slider.get()
        _start_col_no = self.position_frames['start'].column.slider.get()
        self.start_arg = "{}.{}".format(_start_line_no, _start_col_no)
        if self._is_two_args.var.get():
            _end_line_no = self.position_frames['end'].line.slider.get()
            _end_col_no = self.position_frames['end'].column.slider.get()
            self.end_arg = "{}.{}".format(_end_line_no, _end_col_no)
        else:
            self.end_arg = None
        self._update_method_labels()
        self._select()


    def _update_method_labels(self):
        if self.end_arg:
            for _key in self.position_frames:
                _string = "text.get('{}', '{}')".format(
                                                self.start_arg, self.end_arg)
                self.position_frames[_key].label['text'] = _string
        else:
            _string = "text.get('{}')".format(self.start_arg)
            self.position_frames['start'].label['text'] = _string


    def _select(self):
        self.text.focus_set()
        self.text.tag_remove('sel', '1.0', 'end')
        self.text.tag_add('sel', self.start_arg, self.end_arg)
        if self.end_arg:
            self.text.mark_set('insert', self.end_arg)
        else:
            self.text.mark_set('insert', self.start_arg)


class TextWithStats(tk.Text):
    """
    Text widget that stores stats of its content:
    self.line_count:        the total number of lines
    self.lines_length:      the total number of characters per line
    self.update_callback:   can be set as the reference to the callback
                            to be called with each update
    """

    def __init__(self, master, update_callback=None, *args, **kwargs):
        tk.Text.__init__(self, master, *args, **kwargs)
        self._events = ('<KeyPress>',
                        '<KeyRelease>',
                        '<ButtonRelease-1>',
                        '<ButtonRelease-2>',
                        '<ButtonRelease-3>',
                        '<Delete>',
                        '<<Cut>>',
                        '<<Paste>>',
                        '<<Undo>>',
                        '<<Redo>>')
        self.line_count = None
        self.lines_length = list()
        self.update_callback = update_callback
        self.update_stats()
        self.bind_events_on_widget_to_callback( self._events,
                                                self,
                                                self.update_stats)


    @staticmethod
    def bind_events_on_widget_to_callback(events, widget, callback):
        """
        Bind events on widget to callback.
        """

        for _event in events:
            widget.bind(_event, callback)


    def update_stats(self, event=None):
        """
        Update self.line_count, self.lines_length stats and call
        self.update_callback.
        """

        _string = self.get('1.0', 'end-1c')
        _string_lines = _string.splitlines()
        self.line_count = len(_string_lines)
        del self.lines_length[:]
        for _line in _string_lines:
            self.lines_length.append(len(_line))
        if self.update_callback:
            self.update_callback()


class PositionFrame(tk.LabelFrame):
    """
    A LabelFrame that has two LabelFrames which has Scales.
    """

    def __init__(self, master, *args, **kwargs):
        tk.LabelFrame.__init__(self, master, *args, **kwargs)
        self._create_widgets()
        self._layout()


    def _create_widgets(self):
        self.line = SliderFrame(self, orient='vertical', text="line=")
        self.column = SliderFrame(self, orient='horizontal', text="column=")
        self.label = tk.Label(self, text="Label")


    def _layout(self):
        self.line.grid(sticky='ns', row=0, column=0, rowspan=2)
        self.column.grid(sticky='ew', row=0, column=1, columnspan=2)
        self.label.grid(sticky='nsew', row=1, column=1)
        self.grid_rowconfigure(1, weight=1)
        self.grid_columnconfigure(1, weight=1)


class SliderFrame(tk.LabelFrame):
    """
    A LabelFrame that encapsulates a Scale.
    """

    def __init__(self, master, orient, *args, **kwargs):
        tk.LabelFrame.__init__(self, master, *args, **kwargs)

        self.slider = tk.Scale(self, orient=orient)
        self.slider.pack(fill='both', expand=True)


if __name__ == '__main__':
    root = tk.Tk()
    demo = Demo(root, text="text.get(start, end=None)")

    with open(__file__) as f:
        demo.text.insert('1.0', f.read())
    demo.text.update_stats()
    demo.pack(fill='both', expand=True)
    root.mainloop()

回答by bhaskar

I think this is a better way-

我认为这是一个更好的方法-

variable1=StringVar() # Value saved here

def search():
  print(variable1.get())
  return ''

ttk.Entry(mainframe, width=7, textvariable=variable1).grid(column=2, row=1)

ttk.Label(mainframe, text="label").grid(column=1, row=1)

ttk.Button(mainframe, text="Search", command=search).grid(column=2, row=13)

On pressing the button, the value in the text field would get printed. But make sure You import the ttk separately.

按下按钮时,将打印文本字段中的值。但请确保您单独导入 ttk。

The full codefor a basic applicationis-

完整的代码基础的应用程序是-

from tkinter import *
from tkinter import ttk

root=Tk()
mainframe = ttk.Frame(root, padding="10 10 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)


variable1=StringVar() # Value saved here

def search():
  print(variable1.get())
  return ''

ttk.Entry(mainframe, width=7, textvariable=variable1).grid(column=2, row=1)

ttk.Label(mainframe, text="label").grid(column=1, row=1)

ttk.Button(mainframe, text="Search", command=search).grid(column=2, row=13)

root.mainloop()

回答by Adam Rajczakowski

Lets say that you have a Textwidget called my_text_widget.

假设您有一个Text名为my_text_widget.

To getinput from the my_text_widgetyou can use the getfunction.

要从获取输入,my_text_widget您可以使用该get函数。

Let's assume that you have imported tkinter. Lets define my_text_widgetfirst, lets make it just a simple text widget.

假设您已导入tkinter. 让我们my_text_widget先定义,让它只是一个简单的文本小部件。

my_text_widget = Text(self)

To getinput from a textwidget you need to use the getfunction, both, textand entrywidgets have this.

要从小部件获取输入,text您需要使用该get功能,text并且entry小部件都具有此功能。

input = my_text_widget.get()

The reason we save it to a variable is to use it in the further process, for example, testing for what's the input.

我们将它保存到变量的原因是为了在进一步的过程中使用它,例如,测试输入是什么。

回答by Javad Norouzi

I faced the problem of gettng entire text from Text widget and following solution worked for me :

我遇到了从 Text 小部件获取整个文本的问题,以下解决方案对我有用:

txt.get(1.0,END)

Where 1.0 means first line, zeroth character (ie before the first!) is the starting position and END is the ending position.

其中 1.0 表示第一行,第零个字符(即在第一个之前!)是起始位置,END 是结束位置。

Thanks to Alan Gauld in this link

感谢 Alan Gauld 在此链接中