Wie erhalte ich die Eingabe vom Tkinter Text Widget?


98

Wie bekomme ich Tkinter-Eingaben vom TextWidget?

BEARBEITEN

Ich habe diese Frage gestellt, um anderen bei demselben Problem zu helfen - aus diesem Grund gibt es keinen Beispielcode. Dieses Problem hatte mich stundenlang beunruhigt und ich benutzte diese Frage, um andere zu unterrichten. Bitte bewerten Sie es nicht so, als wäre es eine echte Frage - die Antwort ist das, worauf es ankommt.

Antworten:


132

Um Tkinter-Eingaben aus dem Textfeld zu erhalten, müssen Sie der normalen .get()Funktion einige weitere Attribute hinzufügen . Wenn wir ein Textfeld haben myText_Box, ist dies die Methode zum Abrufen der Eingabe.

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

Der erste Teil "1.0"bedeutet, dass die Eingabe aus Zeile 1, Zeichen Null (dh das allererste Zeichen) gelesen werden soll. ENDist eine importierte Konstante, die auf die Zeichenfolge festgelegt wird "end". Der ENDTeil bedeutet lesen, bis das Ende des Textfeldes erreicht ist. Das einzige Problem dabei ist, dass es unserer Eingabe tatsächlich eine neue Zeile hinzufügt. Um dies zu beheben, sollten wir ENDzu end-1c(Danke Bryan Oakley ) wechseln. Das -1clöscht 1 Zeichen, während -2cdas Löschen von zwei Zeichen und so weiter bedeuten würde.

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

20
Sie sollten "end-1c"oder END+"1c", sonst erhalten Sie die zusätzliche neue Zeile, die das Text-Widget immer hinzufügt.
Bryan Oakley

2
@xxmbabanexx: Nein, "-1c" bedeutet "minus ein Zeichen".
Bryan Oakley

2
Dies ist, was Sie wollen:.get('1.0', 'end-1c')
Honest Abe

1
Vielen Dank! Nur aus Neugier, wenn ich schreiben end+1cwürde, würde das dem Code eine neue Zeile hinzufügen? Zum Schluss, Bryan und Honest Abe, vielen Dank, dass Sie mir bei meinen einfachen Tkinter- und Python-Fragen geholfen haben. Sie haben mir wirklich geholfen, ein tieferes Verständnis der Sprache zu erlangen, und waren immer höflich, schnell und am besten - kenntnisreich. Ich bin sicher, dass Ihr Rat mir helfen wird, wenn ich zur Highschool und darüber hinaus gehe!
xxmbabanexx

1
Das Beispiel, das Sie hinzugefügt haben, funktioniert nicht. Die Anführungszeichen 'end-1c'sind erforderlich, damit es sich um eine einzelne Zeichenfolge handelt. 'end'ist ein Alias ​​für den Index nach dem letzten Zeichen. Wenn also 'end'war '3.8'dann 'end-1c'wäre '3.7'. Ich möchte noch einmal empfehlen, Folgendes zu überprüfen: Text-Widget-Indizes .
Ehrliche Abe

19

So habe ich es mit Python 3.5.2 gemacht:

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()

Als ich damit "bla bla" in das Text-Widget tippte und die Taste drückte, wurde alles, was ich tippte, ausgedruckt. Ich denke, das ist die Antwort für das Speichern von Benutzereingaben vom Text-Widget in die Variable.


9

Um Tkinter-Eingaben aus dem Textfeld in Python 3 zu erhalten, ist das von mir verwendete vollständige Programm auf Schülerebene wie folgt:

#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()

6

Um die Zeichenfolge in einem TextWidget zu erhalten, kann einfach eine getdefinierte Methode verwendet werden, für Textdie 1 bis 2 Argumente als startund endPositionen von Zeichen akzeptiert werden text_widget_object.get(start, end=None). Wenn nur übergeben startwird und endnicht übergeben wird, wird nur das einzelne Zeichen zurückgegeben, das bei startif positioniert istend es ebenfalls übergeben wird, werden alle Zeichen zwischen den Positionen startund zurückgegebenend als Zeichenfolge zurückgegeben.

Es gibt auch spezielle Zeichenfolgen, die Variablen für das zugrunde liegende Tk sind. Einer von ihnen wäre "end"odertk.END repräsentiert die variable Position des allerletzten Zeichens im TextWidget. Ein Beispiel wäre die Rückgabe des gesamten Textes im Widget mit text_widget_object.get('1.0', 'end')odertext_widget_object.get('1.0', 'end-1c') wenn Sie nicht das letzte Zeilenumbruchzeichen möchten.

Demo

Siehe folgende Demonstration, in der die Zeichen zwischen den angegebenen Positionen mit Schiebereglern ausgewählt werden:

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()

1

Ich denke, das ist ein besserer Weg.

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)

Beim Drücken der Taste wird der Wert im Textfeld gedruckt. Stellen Sie jedoch sicher, dass Sie das ttk separat importieren.

Der vollständige Code für eine grundlegende Anwendung is-

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()

0

Ich hatte das Problem, den gesamten Text aus dem Text-Widget abzurufen, und die folgende Lösung hat bei mir funktioniert:

txt.get(1.0,END)

Wobei 1.0 die erste Zeile bedeutet, ist das nullte Zeichen (dh vor der ersten!) Die Startposition und END die Endposition.

Vielen Dank an Alan Gauld in diesem Link


-3

Nehmen wir an, Sie haben ein TextWidget namensmy_text_widget .

Um zu erhalten Eingang von dem my_text_widgetSie können die Verwendungget Funktion.

Nehmen wir an, Sie haben importiert tkinter. Definieren wir my_text_widgetzuerst, machen wir es einfach zu einem einfachen Text-Widget.

my_text_widget = Text(self)

Um zu erhalten Eingabe von einem textWidget müssen Sie die verwenden getFunktion, beide, textund entryWidgets haben diese.

input = my_text_widget.get()

Der Grund, warum wir es in einer Variablen speichern, besteht darin, es im weiteren Prozess zu verwenden, z. B. um zu testen, was die Eingabe ist.


1
Diese Antwort ist falsch. Die TextWidget- getMethode erfordert mindestens ein Argument.
Bryan Oakley
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.