Как установить текст/значение/содержимое виджета "Запись" с помощью кнопки в tkinter

Я пытаюсь установить текст виджета Entry используя кнопку в графическом интерфейсе, используя модуль tkinter.

Этот графический интерфейс, чтобы помочь мне классифицировать тысячи слов на пять категорий. У каждой из категорий есть кнопка. Я надеялся, что использование кнопки значительно ускорит меня, и я хочу дважды проверять слова каждый раз, в противном случае я просто использовал бы кнопку, чтобы графический интерфейс обрабатывал текущее слово и выводил следующее слово.

Командные кнопки почему-то не ведут себя так, как я хочу. Это пример:

win = Tk()

v = StringVar()
def setText(word):
    v.set(word)

a = Button(win, text="plant", command=setText("plant")
a.pack()
b = Button(win, text="animal", command=setText("animal"))
b.pack()
c = Entry(win, textvariable=v)
c.pack()
win.mainloop()

Пока, когда я могу скомпилировать, щелчок ничего не делает.

Ответ 1

Возможно, вы захотите использовать метод insert.

Этот script вставляет текст в Entry. Вставляемый текст можно изменить в параметре command кнопки.

from tkinter import *

def set_text(text):
    e.delete(0,END)
    e.insert(0,text)
    return

win = Tk()

e = Entry(win,width=10)
e.pack()

b1 = Button(win,text="animal",command=lambda:set_text("animal"))
b1.pack()

b2 = Button(win,text="plant",command=lambda:set_text("plant"))
b2.pack()

win.mainloop()

Ответ 2

Если вы используете "текстовую переменную" tk.StringVar(), вы можете просто set() это.

Не нужно использовать удаление и вставить запись. Более того, эти функции не работают, когда запись отключена или только для чтения! Однако метод текстовой переменной работает и в этих условиях.

import Tkinter as tk

...

entryText = tk.StringVar()
entry = tk.Entry( master, textvariable=entryText )
entryText.set( "Hello World" )

Ответ 3

Вы можете выбрать один из следующих двух методов, чтобы установить текст виджета Entry. Для примеров предположим, что импортированная библиотека import tkinter as tk а корневое окно root = tk.Tk().


  • Способ A: используйте delete и insert

    Entry виджета предоставляет методы delete и insert которые можно использовать для установки нового текста. Во-первых, вам нужно удалить любой прежний, старый текст из Entry с помощью delete который нуждается в позициях, где можно начинать и заканчивать удаление. Так как мы хотим удалить полный старый текст, мы начинаем с 0 и заканчиваем там, где конец находится в данный момент. Мы можем получить доступ к этому значению через END. После этого Entry пуста, и мы можем вставить new_text в позицию 0.

    entry = tk.Entry(root)
    new_text = "Example text"
    entry.delete(0, tk.END)
    entry.insert(0, new_text)
    

  • Метод Б: использовать StringVar

    Вы должны создать новый StringVar объект под названием entry_text в примере. Кроме того, ваш виджет Entry должен быть создан с ключевым аргументом textvariable. После этого каждый раз, когда вы изменяете entry_text с помощью set, текст будет автоматически отображаться в виджете Entry.

    entry_text = tk.StringVar()
    entry = tk.Entry(root, textvariable=entry_text)
    new_text = "Example text"
    entry_text.set(new_text)
    

  • Полный рабочий пример, который содержит оба метода для установки текста с помощью Button :

    Это окно

    screenshot

    генерируется следующим полным рабочим примером:

    import tkinter as tk
    
    def button_1_click():
        # define new text (you can modify this to your needs!)
        new_text = "Button 1 clicked!"
        # delete content from position 0 to end
        entry.delete(0, tk.END)
        # insert new_text at position 0
        entry.insert(0, new_text)
    
    def button_2_click():
        # define new text (you can modify this to your needs!)
        new_text = "Button 2 clicked!"
        # set connected text variable to new_text
        entry_text.set(new_text)
    
    root = tk.Tk()
    
    entry_text = tk.StringVar()
    entry = tk.Entry(root, textvariable=entry_text)
    
    button_1 = tk.Button(root, text="Button 1", command=button_1_click)
    button_2 = tk.Button(root, text="Button 2", command=button_2_click)
    
    entry.pack(side=tk.TOP)
    button_1.pack(side=tk.LEFT)
    button_2.pack(side=tk.LEFT)
    
    root.mainloop()
    

Ответ 4

Одним из способов было бы наследовать новый класс EntryWithSet и определять метод set, который использует delete и insert методы Entry объекты класса:

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


class EntryWithSet(tk.Entry):
    """
    A subclass to Entry that has a set method for setting its text to
    a given string, much like a Variable class.
    """

    def __init__(self, master, *args, **kwargs):
        tk.Entry.__init__(self, master, *args, **kwargs)


    def set(self, text_string):
        """
        Sets the object text to text_string.
        """

        self.delete('0', 'end')
        self.insert('0', text_string)


def on_button_click():
    import random, string
    rand_str = ''.join(random.choice(string.ascii_letters) for _ in range(19))
    entry.set(rand_str)


if __name__ == '__main__':
    root = tk.Tk()
    entry = EntryWithSet(root)
    entry.pack()
    tk.Button(root, text="Set", command=on_button_click).pack()
    tk.mainloop()

Ответ 5

Ваша проблема в том, что когда вы это делаете:

a = Button(win, text="plant", command=setText("plant"))

он пытается оценить, что нужно установить для команды. Поэтому при создании экземпляра объекта Button он фактически вызывает setText("plant"). Это неправильно, потому что вы еще не хотите называть метод setText. Затем он принимает возвращаемое значение этого вызова (которое равно None) и устанавливает его команде команды. Поэтому нажатие кнопки ничего не делает, потому что для нее нет команды.

Если вы сделаете так, как предложил Милан Scala, и вместо этого используйте выражение лямбда, тогда ваш код будет работать (если вы исправите отступы и круглые скобки).

Вместо command=setText("plant"), которая на самом деле вызывает функцию, вы можете установить command=lambda:setText("plant") которая указывает то, что вызовет функцию позже, когда вы хотите ее вызвать.

Если вам не нравятся лямбды, другой (немного более громоздкий) способ состоит в том, чтобы определить пару функций, которые вы хотите делать:

def set_to_plant():
    set_text("plant")
def set_to_animal():
    set_text("animal")

а затем вы можете использовать command=set_to_plant и command=set_to_animal - они будут оцениваться соответствующими функциями, но определенно не совпадают с command=set_to_plant() которые, конечно же, снова оценивают значение None.

Ответ 6

e= StringVar()
def fileDialog():
    filename = filedialog.askopenfilename(initialdir = "/",title = "Select A 
    File",filetype = (("jpeg","*.jpg"),("png","*.png"),("All Files","*.*")))
    e.set(filename)
la = Entry(self,textvariable = e,width = 30).place(x=230,y=330)
butt=Button(self,text="Browse",width=7,command=fileDialog).place(x=430,y=328)