162 votes

Comment obtenir l'entrée du Widget Texte de Tkinter ?

Comment obtenir une entrée Tkinter à partir du Text widget ?

EDIT

J'ai posé cette question pour aider d'autres personnes ayant le même problème. que est la raison pour laquelle il n'y a pas de code d'exemple. Cette question m'a troublé pendant des heures et j'ai utilisé cette question pour enseigner aux autres. S'il vous plaît ne le notez pas comme s'il s'agissait d'une vraie question - c'est la réponse qui compte.

215voto

xxmbabanexx Points 964

Pour obtenir une entrée Tkinter à partir de la zone de texte, vous devez ajouter quelques attributs supplémentaires à l'attribut normal .get() fonction. Si nous avons une zone de texte myText_Box alors c'est la méthode pour récupérer son entrée.

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

La première partie, "1.0" signifie que l'entrée doit être lue à partir de la ligne un, caractère zéro (c'est-à-dire le tout premier caractère). END est une constante importée qui est définie comme la chaîne de caractères "end" . Le site END signifie qu'il faut lire jusqu'à ce que la fin de la zone de texte soit atteinte. Le seul problème est que cela ajoute une nouvelle ligne à notre entrée. Pour résoudre ce problème, nous devons donc modifier les éléments suivants END a end-1c (Merci Bryan Oakley ) Le -1c supprime 1 caractère, tandis que -2c signifierait supprimer deux caractères, et ainsi de suite.

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

32voto

Skarga Points 251

Voici comment j'ai procédé avec 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()

Avec cela, lorsque j'ai tapé "blah blah" dans le widget texte et appuyé sur le bouton, ce que j'ai tapé a été imprimé. Je pense donc que c'est la solution pour stocker l'entrée de l'utilisateur du widget de texte dans une variable.

9voto

Abdul Wahid Points 461

Pour obtenir une entrée Tkinter à partir de la zone de texte en python 3, le programme complet de niveau étudiant utilisé par moi est le suivant :

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

8voto

Nae Points 5451

Afin d'obtenir la chaîne de caractères dans un Text on peut simplement utiliser le widget get méthode définie pour Text qui accepte 1 à 2 arguments comme start y end les positions des caractères, text_widget_object.get(start, end=None) . Si seulement start est passé et end n'est pas passé, il retourne seulement le caractère unique positionné à start si end est passé également, il renvoie tous les caractères entre les positions start y end en tant que chaîne de caractères.

Il existe également des chaînes spéciales, qui sont variables au Tk sous-jacent. L'un d'eux serait "end" o tk.END qui représente la position de la variable du tout dernier caractère dans le fichier Text widget. Un exemple serait de retourner tout le texte dans le widget, avec text_widget_object.get('1.0', 'end') o text_widget_object.get('1.0', 'end-1c') si vous ne voulez pas le dernier caractère de nouvelle ligne.

Démo

Voir ci-dessous la démonstration que sélectionne les caractères entre les positions données avec des curseurs :

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

5voto

Javad Norouzi Points 119

J'ai rencontré le problème de récupérer le texte entier du widget Texte et la solution suivante a fonctionné pour moi :

txt.get(1.0,END)

Où 1.0 signifie première ligne, caractère zéro (c'est-à-dire avant le premier !) est la position de départ et END est la position de fin.

Merci à Alan Gauld dans ce lien

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X