Comment obtenir l'entrée du widget de texte Tkinter?

98

Comment obtenir l'entrée Tkinter du Textwidget?

ÉDITER

J'ai posé cette question pour aider les autres avec le même problème - c'est la raison pour laquelle il n'y a pas d'exemple de code. Ce problème m'inquiétait depuis des heures et j'ai utilisé cette question pour enseigner aux autres. Veuillez ne pas l'évaluer comme s'il s'agissait d'une vraie question - la réponse est ce qui compte.

xxmbabanexx
la source

Réponses:

132

Pour obtenir l'entrée Tkinter à partir de la zone de texte, vous devez ajouter quelques attributs supplémentaires à la .get()fonction normale . 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 première ligne, le caractère zéro (c'est-à-dire le tout premier caractère). ENDest une constante importée définie sur la chaîne "end". La ENDpartie signifie lire jusqu'à ce que la fin de la zone de texte soit atteinte. Le seul problème avec ceci est qu'il ajoute en fait une nouvelle ligne à notre entrée. Donc, pour résoudre ce problème, nous devrions changer ENDpour end-1c(Merci Bryan Oakley ) Le caractère -1csupprime 1, alors que -2ccela signifierait supprimer deux caractères, et ainsi de suite.

def retrieve_input():
    input = self.myText_Box.get("1.0",'end-1c')
xxmbabanexx
la source
20
Vous devriez faire "end-1c"ou END+"1c", sinon vous obtiendrez la nouvelle ligne supplémentaire que le widget de texte ajoute toujours.
Bryan Oakley
2
@xxmbabanexx: Non, "-1c" signifie "moins un caractère".
Bryan Oakley
2
Voici ce que vous voulez:.get('1.0', 'end-1c')
Honest Abe
1
Merci! Juste par curiosité, si je devais écrire, est- end+1cce que cela ajouterait une nouvelle ligne au code? Enfin, Bryan et Honest Abe, merci beaucoup de m'avoir aidé avec mes simples questions sur Tkinter et Python. Vous m'avez vraiment aidé à acquérir une meilleure compréhension de la langue, et vous avez toujours été courtois, rapide et, mieux que tout, bien informé. Je suis sûr que vos conseils m'aideront alors que je vais au lycée et au-delà!
xxmbabanexx
1
L'exemple que vous avez ajouté ne fonctionne pas. Les guillemets autour 'end-1c'sont nécessaires pour qu'il s'agisse d'une seule chaîne. 'end'est un alias pour l'index après le dernier caractère. Donc si 'end'c'était '3.8'alors ce 'end-1c'serait '3.7'. Je veux à nouveau recommander de revoir: Index des widgets de texte .
Honest Abe
19

Voici comment je l'ai fait 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, quand j'ai tapé "bla bla" dans le widget texte et appuyé sur le bouton, tout ce que j'ai tapé était imprimé. Je pense donc que c'est la solution pour stocker les entrées utilisateur du widget Texte vers la variable.

Skarga
la source
9

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()
Abdul Wahid
la source
6

Afin d'obtenir la chaîne dans un Textwidget on peut simplement utiliser la getméthode définie pour Textlaquelle accepte 1 à 2 arguments comme startet endpositions de caractères text_widget_object.get(start, end=None),. Si seulement startest passé et endn'est pas passé, il ne renvoie que le caractère unique positionné sur start, si end est également passé, il renvoie tous les caractères entre les positions startet endsous forme de chaîne.

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

Démo

Voir la démonstration ci-dessous qui 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()
Nae
la source
2

Je pense que c'est une meilleure façon

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)

En appuyant sur le bouton, la valeur dans le champ de texte serait imprimée. Mais assurez-vous d'importer le ttk séparément.

Le code complet d'une application de base est:

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()
Bhaskar
la source
0

J'ai rencontré le problème d'obtenir le texte entier du widget Texte et la solution suivante a fonctionné pour moi:

txt.get(1.0,END)

Où 1.0 signifie la première ligne, le 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

Javad Norouzi
la source
-3

Disons que vous avez un Textwidget appelé my_text_widget.

Pour obtenir des informations du, my_text_widgetvous pouvez utiliser leget fonction.

Supposons que vous ayez importé tkinter. Définissons d' my_text_widgetabord, faisons-en juste un simple widget de texte.

my_text_widget = Text(self)

Pour obtenir l' entrée d'un textwidget, vous devez utiliser la getfonction, les widgets textet les deux l' entryont.

input = my_text_widget.get()

La raison pour laquelle nous l'enregistrons dans une variable est de l'utiliser dans le processus ultérieur, par exemple, pour tester quelle est l'entrée.

Adam Rajczakowski
la source
1
Cette réponse est incorrecte. La méthode Textwidget getnécessite au moins un argument.
Bryan Oakley