Bagaimana cara mendapatkan input dari Tkinter Text Widget?


102

Bagaimana cara mendapatkan masukan Tkinter dari Textwidget?

EDIT

Saya menanyakan pertanyaan ini untuk membantu orang lain dengan masalah yang sama - itulah alasan mengapa tidak ada kode contoh. Masalah ini telah mengganggu saya selama berjam-jam dan saya menggunakan pertanyaan ini untuk mengajar orang lain. Tolong jangan menilai seolah-olah itu adalah pertanyaan nyata - jawabannya adalah hal yang penting.

Jawaban:


136

Untuk mendapatkan masukan Tkinter dari kotak teks, Anda harus menambahkan beberapa atribut lagi ke .get()fungsi normal . Jika kita memiliki kotak teks myText_Box, maka ini adalah metode untuk mengambil masukannya.

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

Bagian pertama, "1.0"berarti bahwa input harus dibaca dari baris pertama, karakter nol (yaitu: karakter pertama). ENDadalah konstanta yang diimpor yang disetel ke string "end". Bagian ENDberarti membaca sampai akhir kotak teks tercapai. Satu-satunya masalah dengan ini adalah itu benar-benar menambahkan baris baru ke masukan kita. Jadi, untuk memperbaikinya kita harus mengubah ENDke end-1c(Terima kasih Bryan Oakley ) -1cMenghapus 1 karakter, sementara -2citu berarti menghapus dua karakter, dan seterusnya.

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

20
Anda harus melakukan "end-1c"atau END+"1c", jika tidak, Anda akan mendapatkan baris baru ekstra yang selalu ditambahkan widget teks.
Bryan Oakley

2
@xxmbabanexx: Tidak, "-1c" berarti "minus satu karakter".
Bryan Oakley

2
Inilah yang Anda inginkan:.get('1.0', 'end-1c')
Honest Abe

1
Terima kasih! Hanya karena penasaran, jika saya menulis, end+1capakah itu akan menambah baris baru ke kode? Terakhir, Bryan dan Honest Abe, terima kasih banyak telah membantu saya menjawab pertanyaan Tkinter dan Python saya yang sederhana. Anda benar-benar telah membantu saya untuk mendapatkan pemahaman yang lebih dalam tentang bahasa tersebut, dan selalu sopan, cepat, dan yang terbaik dari semuanya - berpengetahuan. Saya yakin nasihat Anda akan membantu saya saat saya pindah ke sekolah menengah dan seterusnya!
xxmbabanexx

1
Contoh yang Anda tambahkan tidak berfungsi. Kutipan di sekitar 'end-1c'diperlukan agar menjadi string tunggal. 'end'adalah alias untuk indeks setelah karakter terakhir. Jadi jika 'end'itu '3.8'maka 'end-1c'akan '3.7'. Saya ingin sekali lagi merekomendasikan untuk meninjau: Indeks widget teks .
Jujur Abe

19

Inilah cara saya melakukannya dengan 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()

dengan itu, ketika saya mengetik "blah blah" di widget teks dan menekan tombol, apa pun yang saya ketikkan akan dicetak. Jadi saya pikir itulah jawaban untuk menyimpan input pengguna dari widget Teks ke variabel.


9

Untuk mendapatkan input Tkinter dari kotak teks di python 3 program tingkat siswa lengkap yang saya gunakan adalah sebagai berikut:

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

7

Untuk mendapatkan string dalam Textwidget, seseorang cukup menggunakan getmetode yang ditentukan Textyang menerima 1 hingga 2 argumen sebagai startdan endposisi karakter , text_widget_object.get(start, end=None). Jika hanya startdilewatkan dan endtidak lulus itu kembali hanya satu karakter diposisikan pada start, jika end yang lulus juga, ia mengembalikan semua karakter di antara posisi startdan endsebagai string.

Ada juga string khusus, yaitu variabel ke Tk yang mendasarinya. Salah satunya adalah "end"atau tk.ENDyang mewakili posisi variabel dari karakter terakhir di Textwidget. Contohnya adalah mengembalikan semua teks di widget, dengan text_widget_object.get('1.0', 'end')atautext_widget_object.get('1.0', 'end-1c') jika Anda tidak menginginkan karakter baris baru terakhir.

Demo

Lihat demonstrasi di bawah ini yang memilih karakter di antara posisi yang diberikan dengan slider:

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

Saya pikir ini adalah cara yang lebih baik-

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)

Saat menekan tombol, nilai di bidang teks akan dicetak. Tapi pastikan Anda mengimpor ttk secara terpisah.

The kode lengkap untuk aplikasi dasar adalah-

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

Saya menghadapi masalah mendapatkan seluruh teks dari widget Teks dan solusi berikut berhasil untuk saya:

txt.get(1.0,END)

Dimana 1.0 berarti baris pertama, karakter nol (yaitu sebelum yang pertama!) Adalah posisi awal dan AKHIR adalah posisi akhir.

Terima kasih untuk Alan Gauld di tautan ini


0

Saya juga datang untuk mencari cara mendapatkan data masukan dari widget Teks. Mengenai masalah dengan baris baru di ujung string. Anda bisa menggunakan .strip () karena ini adalah widget Teks yang selalu berupa string.

Selain itu, saya membagikan kode di mana Anda dapat melihat bagaimana Anda dapat membuat banyak widget Teks dan menyimpannya dalam kamus sebagai data formulir, lalu dengan mengklik tombol kirim dapatkan data formulir itu dan lakukan apa pun yang Anda inginkan. Saya harap ini membantu orang lain. Ini harus bekerja di python 3.x dan mungkin akan bekerja di 2.7 juga.

from tkinter import *
from functools import partial

class SimpleTkForm(object):
    def __init__(self):
        self.root = Tk()

    def myform(self):
        self.root.title('My form')
        frame = Frame(self.root, pady=10)
        form_data = dict()
        form_fields = ['username', 'password', 'server name', 'database name']
        cnt = 0
        for form_field in form_fields:
            Label(frame, text=form_field, anchor=NW).grid(row=cnt,column=1, pady=5, padx=(10, 1), sticky="W")
            textbox = Text(frame, height=1, width=15)
            form_data.update({form_field: textbox})
            textbox.grid(row=cnt,column=2, pady=5, padx=(3,20))
            cnt += 1

        conn_test = partial(self.test_db_conn, form_data=form_data)
        Button(frame, text='Submit', width=15, command=conn_test).grid(row=cnt,column=2, pady=5, padx=(3,20))
        frame.pack()
        self.root.mainloop()

    def test_db_conn(self, form_data):
        data = {k:v.get('1.0', END).strip() for k,v in form_data.items()}
        # validate data or do anything you want with it
        print(data)


if __name__ == '__main__':
    api = SimpleTkForm()
    api.myform()

-3

Katakanlah Anda memiliki Textwidget bernama my_text_widget.

Untuk mendapatkan masukan dari my_text_widgetAnda dapat menggunakan getfungsi tersebut.

Anggaplah Anda telah mengimpor tkinter. Mari kita tentukan my_text_widgetdulu, mari kita membuatnya hanya widget teks sederhana.

my_text_widget = Text(self)

Untuk mendapatkan masukan dari textwidget Anda perlu menggunakan getfungsi, textdan entrywidget memiliki ini.

input = my_text_widget.get()

Alasan kami menyimpannya ke variabel adalah untuk menggunakannya dalam proses lebih lanjut, misalnya, menguji apa inputnya.


1
Jawaban ini salah. The Textwidget getMetode membutuhkan setidaknya satu argumen.
Bryan Oakley
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.