2013-02-12 15 views
44

Come ottenere input Tkinter dalla casella Testo in Python 2.7.3?Come ottenere l'input dal Widget TKinter Text Box?

EDIT

ho fatto questa domanda per aiutare gli altri con lo stesso problema - che è il motivo per cui non v'è alcun codice di esempio. Questo problema mi ha turbato per ore e ho usato questa domanda per insegnare agli altri. Si prega di non valutarlo come se fosse una vera domanda - la risposta è la cosa che conta.

risposta

59

Per ottenere input Tkinter dalla casella di testo, è necessario aggiungere alcuni altri attributi alla normale funzione .get(). 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'ingresso deve essere letto da una linea, carattere zero (cioè: il primo carattere). END è una costante importata che è impostata sulla stringa "end". La parte END significa leggere fino al raggiungimento della fine della casella di testo. L'unico problema con questo è che in realtà aggiunge una nuova riga al nostro input. Quindi, per risolverlo dovremmo cambiare END a end-1c (Grazie Bryan Oakley) Il -1c cancella 1 carattere, mentre -2c significherebbe eliminare due caratteri e così via.

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

Si dovrebbe fare ' "end-1c"' o 'END + "1c"', altrimenti otterrai la nuova riga aggiuntiva che il widget di testo aggiunge sempre. –

+0

@Bryan Oakley Grazie, quindi '-1c/1c'mean" cancella una nuova riga? " Inoltre, può essere utilizzato in aree diverse dal widget di testo/Tkinter? – xxmbabanexx

+0

Controlla la sezione del widget Testo del [riferimento NMTech] (http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html) → [Indici widget di testo] (http: // infohost .nmt.edu/tcc/help/pubs/tkinter/web/text-index.html) –

4

per ricevere input Tkinter dalla casella di testo in Python 3 il programma completo di livello dell'allievo usato da me è come sotto:

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

Ecco come 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 quello, quando ho digitato "blah blah" nel widget di testo e premuto il pulsante, qualunque cosa ho digitato è stato stampato. Quindi penso che sia la risposta per la memorizzazione dell'input dell'utente dal widget Testo alla variabile.

0

Per ottenere la stringa in un widget Text si può semplicemente utilizzare get metodo definito per Text che accetta 1 a 2 argomenti start e end posizioni dei caratteri, text_widget_object.get(start, end=None). Se viene passato solo start e end non si passa restituisce solo il singolo carattere posizionato start, se endè passato pure, restituisce tutti i caratteri tra posizioni start e end come stringa.

Ci sono anche stringhe speciali, che sono variabili alla sottostante Tk. Uno di questi sarebbe "end" o tk.END che rappresenta la posizione variabile dell'ultimo carattere nel widget Text. Un esempio potrebbe essere quello di restituire 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

Vedere sotto dimostrazione che seleziona i personaggi tra le posizioni indicate 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() 
Problemi correlati