Tkinter - Как изменить значение аргумента для привязки события с помощью лямбда-функции?

У меня есть список с именем chosenTestHolder (импортированный из файла my_config), который состоит из нескольких объектов, каждый из которых имеет атрибут «предложение».

При первом нажатии кнопки «Нажать» атрибут «предложение» первого объекта в chosenTestHolder должен отображаться в текстовом виджете. При следующем нажатии кнопки «Нажать» должен отображаться атрибут «предложение» второго объекта в chosenTestHolder и так далее.

Я использую лямбда-событие для привязки кнопки «Нажать» и пытаюсь использовать новые предложения в качестве своих первых аргументов после каждого нажатия кнопки «Нажать». Однако он продолжает показывать первое предложение.

При поиске в Stackoverflow я видел в использование лямбда-функции для изменения значения атрибут, что вы не можете использовать присваивания в лямбда-выражениях, но, прочитав это, я до сих пор не понял, как решить мою проблему.

Благодарен за помощь! Код ниже!

main.py

from tkinter import font
import tkinter as tk
import tkinter.ttk as ttk

import my_config 
import Testlist as tl


class TestWidgetTest:

  def __init__(self):

        ram               = tk.Frame(root)
        ram.grid(in_=root,row=0, column=0) 
        self.myText       = tk.Text(ram, height = 5)
        self.myText.grid(row=0,column=1)

        my_config.counter = 0

        self.myButton    = tk.Button(ram, text = 'Press')
        self.myButton.grid(row =1, column =0, columnspan =2)
        indata =[my_config.chosenTestHolder[my_config.counter] , self.myText]
        self.myButton.bind('<ButtonRelease-1>',lambda event, arg=indata : self.TagConfigure(event, arg))


  def TagConfigure(self, event, arg):
        arg[1].delete('1.0',tk.END)
        arg[1].insert('1.0',arg[0].sentence)

        my_config.counter += 1


root  = tk.Tk()

TestWidgetTest()
root.mainloop()

my_config.py

import Testlist as tl

testListHolder  = [ ['Fabian was very tired'],
                ['Thomas light the fire'],
                ['Anna eat a red apple ']]

chosenTestHolder = []
count = 0
while count <(len(testListHolder)):  
    chosenTestHolder.append(tl.Testlist(testListHolder[count][0]))
    count += 1  

counter = 0

Список тестов.py

class Testlist:

    def __init__(self, sentence):

       self.sentence   = sentence

person user2423970    schedule 09.02.2018    source источник


Ответы (1)


Ваша проблема заключается в назначении indata. Вы только назначаете в init.

Чтобы ваш код работал, вам нужно перенастроить ваш сентек...

indata =[my_config.chosenTestHolder[my_config.counter] , self.myText]
self.myButton.bind('<ButtonRelease-1>',lambda event, arg=indata : self.TagConfigure(event, arg))

Я бы посоветовал отслеживать текущее предложение как переменную экземпляра.

class Test_widget(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, args, kwargs)
        self.sentences=["a", "b", "c", "d"] # the data
        self.show = tk.StringVar()          # the current displayed data
        self.show.set("NULL")
        self.counter=0                      # the indexer

        tk.Label(self, textvariable=self.show).grid(row=0)
        tk.Button(self, command=self.click).grid(row=1)

    def click(self, event):
        self.show.set("%s"%self.sentences[self.counter]) # use the indexer to access the data
        self.counter = self.counter + 1                  # modify the indexer
        if self.counter = len(self.sentences):           # make sure you dont run in index-err
            self.counter = 0

Как видите, в лямбдах нет никакой необходимости.

Изменить Что касается ваших вопросов:

  1. Изменение исходного кода не было запланировано.
  2. Я не вижу случая использования лямбда-выражения для его использования внутри вашего кода.
    По крайней мере, ни одного случая, когда лямбда-выражение необходимо.
    Пожалуйста, не забывайте использовать лямбда-выражение только и исключительно если
    нет ( == NULL ) других вариантов.
  3. Используя наследование (именно так называется этот механизм), вы можете наследовать функции, поведение "по умолчанию" от других классов. Это распространенный механизм в программировании, а не только для python. Он используется как любой обычный объект, за исключением того, что вам нужно вызвать конструктор базового класса (что я делаю, используя tk.Frame.__init__(self, args, kwargs) внутри метода init). друг, теперь, когда вы знаете, как называется этот механизм).
person R4PH43L    schedule 09.02.2018
comment
Спасибо! Мне все не понятно поэтому у меня вопросы: 1. вы писали: indata =[my_config.chosenTestHolder[my_config.counter] , self.myText] self.myButton.bind('',lambda event, arg=indata : self. TagConfigure(event, arg)) Единственная разница, которую я вижу, это «‹ButtonRelease-1›», замененная на «». Что это означает? 2. Я сократил исходный код. использовалась лямбда (в исходном коде), так как мне нужно было указать несколько параметров. Существует ли «лямбда-решение»? 3. Я новичок в Python, так как же вызвать ваш класс Test_widget с входным аргументом tk.Frame? Спасибо еще раз! - person user2423970; 09.02.2018