Come ottenere l'input dal Tkinter Text Widget?


98

Come ottenere l'input di Tkinter dal Textwidget?

MODIFICARE

Ho posto questa domanda per aiutare altri con lo stesso problema: questo è il motivo per cui non esiste un codice di esempio. Questo problema mi ha turbato per ore e ho usato questa domanda per insegnare agli altri. Per favore , non valutarla come se fosse una vera domanda: la risposta è la cosa che conta.

Risposte:


132

Per ottenere l'input di Tkinter dalla casella di testo, è necessario aggiungere alcuni attributi in più alla .get()funzione normale . Se abbiamo una casella di testo myText_Box, questo è il metodo per recuperare il suo input.

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

La prima parte, "1.0"significa che l'input deve essere letto dalla riga uno, carattere zero (cioè: il primo carattere). ENDè una costante importata che è impostata sulla stringa "end". La ENDparte significa leggere fino a raggiungere la fine della casella di testo. L'unico problema con questo è che in realtà aggiunge una nuova riga al nostro input. Quindi, per risolverlo dovremmo passare ENDa end-1c(Grazie Bryan Oakley ) L' -1celiminazione di 1 carattere, mentre -2csignificherebbe eliminare due caratteri, e così via.

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

20
Dovresti fare "end-1c"o END+"1c", altrimenti otterrai la nuova riga in più che il widget di testo aggiunge sempre.
Bryan Oakley

2
@xxmbabanexx: No, "-1c" significa "meno un carattere".
Bryan Oakley

2
Questo è quello che vuoi:.get('1.0', 'end-1c')
Honest Abe

1
Grazie! Solo per curiosità, se dovessi scrivere end+1caggiungerei una nuova riga al codice? Infine, Bryan e Honest Abe, grazie mille ragazzi per avermi aiutato con le mie semplici domande su Tkinter e Python. Mi hai davvero aiutato ad acquisire una comprensione più profonda della lingua e sei sempre stato cortese, pronto e, soprattutto, ben informato. Sono sicuro che i tuoi consigli mi aiuteranno mentre passo al liceo e oltre!
xxmbabanexx

1
L'esempio che hai aggiunto non funziona. Le virgolette 'end-1c'sono necessarie affinché sia ​​una singola stringa. 'end'è un alias per l'indice dopo l'ultimo carattere. Quindi, se 'end'è stato '3.8'poi 'end-1c'sarebbe '3.7'. Voglio raccomandare di nuovo la revisione: Indici dei widget di testo .
Honest Abe

19

Ecco come l'ho fatto con 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()

con questo, quando ho digitato "blah blah" nel widget di testo e ho premuto il pulsante, tutto ciò che ho digitato è stato stampato. Quindi penso che questa sia la risposta per memorizzare l'input dell'utente dal widget di testo alla variabile.


9

Per ottenere l'input di Tkinter dalla casella di testo in python 3, il programma completo a livello di studente da me utilizzato è il seguente:

#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

Per ottenere la stringa in un Textwidget si può semplicemente utilizzare il getmetodo definito per il Textquale accetta da 1 a 2 argomenti come starte endposizioni di caratteri,text_widget_object.get(start, end=None) ,. Se solo startviene passato e endnon viene passato restituisce solo il singolo carattere posizionato su start, se end viene anche passato restituisce tutti i caratteri tra le posizioni starteend come stringa.

Esistono anche stringhe speciali, che sono variabili per il sottostante Tk. Uno di questi sarebbe "end"o tk.ENDche rappresenta la posizione variabile dell'ultimo carattere nel Textwidget. Un esempio potrebbe essere la restituzione di tutto il testo nel widget, con text_widget_object.get('1.0', 'end')o text_widget_object.get('1.0', 'end-1c')se non si desidera l'ultimo carattere di nuova riga.

Demo

Vedi sotto la dimostrazione che seleziona i caratteri tra le posizioni date con i cursori:

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

2

Penso che questo sia un modo migliore-

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)

Premendo il pulsante, il valore nel campo di testo verrà stampato. Ma assicurati di importare il ttk separatamente.

Il codice completo per un'applicazione di base è-

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

Ho affrontato il problema di ottenere l'intero testo dal widget di testo e la seguente soluzione ha funzionato per me:

txt.get(1.0,END)

Dove 1.0 indica la prima riga, il carattere zero (cioè prima del primo!) È la posizione iniziale e END è la posizione finale.

Grazie ad Alan Gauld in questo link


-3

Diciamo che hai un Textwidget chiamato my_text_widget.

Per ottenere input da my_text_widgetè possibile utilizzare la getfunzione.

Supponiamo che tu abbia importato tkinter. Definiamo my_text_widgetprima, rendiamolo solo un semplice widget di testo.

my_text_widget = Text(self)

Per ottenere l'input da un textwidget di è necessario utilizzare la getfunzione di, sia, texte entrywidgets avere questo.

input = my_text_widget.get()

Il motivo per cui lo salviamo in una variabile è per usarlo nel processo successivo, ad esempio, testando qual è l'input.


1
Questa risposta non è corretta. Il metodo Textwidget getrichiede almeno un argomento.
Bryan Oakley,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.