Кнопка Tkinter, привязанная к клавиатуре, не будет учитывать параметр класса

#python #python-3.x #oop #tkinter #keyboard

#python #python-3.x #ооп #tkinter #клавиатура

Вопрос:

Я пытаюсь создать функцию ‘count’, которая принимает целое число в виде переменной и добавляет к нему 1 при каждом нажатии клавиши возврата, каждый раз сохраняя в переменной.

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

Я попытался создать messi глобальную переменную, поместив global messi ее вверху, но возникает та же проблема.

 import tkinter as tk

class PlayerStats:
    def __init__(self, name, touches):
        team = "Barcelona"
        self.name = name
        self.touches = touches
        
    def count(number):
        number = number   1
        print(number)

messi = PlayerStats("Messi",0)

root = tk.Tk()
root.bind('<Return>', lambda event :PlayerStats.count(messi.touches))
root.mainloop()
 

Когда я запускаю этот фрагмент, он повторяет его один раз, от 0 до 1, а затем сбрасывает, всегда распечатывая 1.

Любые мысли о том, почему это происходит и как исправить, будут оценены!!

Ответ №1:

Вы не сохраняете результат операции.

Вы создаете экземпляр своего PlayerStats класса со значением 0 для touches . Это значение никогда не изменяется во всем вашем коде.

Когда tkinter вызывает ваш count метод, он увеличивается number , но эта переменная никогда не покидает область действия метода и, таким образом, собирается мусор.

Чтобы исправить это, вы должны изменить свой класс на что-то вроде

 import tkinter as tk

class PlayerStats:
    def __init__(self, name, touches):
        team = "Barcelona"
        self.name = name
        self.touches = touches
        
    def count(self):  # the first argument of a method is always a reference to the instance
        self.touches  = 1
        print(self.touches)

messi = PlayerStats("Messi", 0)

root = tk.Tk()
root.bind('<Return>', lambda event: messi.count())  # You need to call the method on the instance you created.
root.mainloop()
 

Комментарии:

1. Не редактируйте код python в виде фрагментов, просто отформатируйте его как код, заключив его в тройные обратные метки или ctrl k или просто скопируйте и вставьте их.

2. спасибо за вашу помощь, это сработало, позволив мне выполнить итерацию переменной и сохранить ее в нужном месте.

Ответ №2:

Спасибо за вашу помощь, Догик. Мой рабочий код сверху теперь выглядит так:

 import tkinter as tk

class PlayerStats:
    def __init__(self, name, touches):
        team = "Barcelona"
        self.name = name
        self.touches = touches
        
    def count(self, number):
        self.touches  = 1
        print(number)

messi = PlayerStats("Messi",0)

root = tk.Tk()
root.bind('<Return>', lambda event :messi.count(messi.touches))
root.mainloop()
 

Единственное, что это не решает, это возможность повторного использования этой функции для разных переменных. Сейчас я пытаюсь придумать элегантный способ сделать что-то вроде этого:
импортировать tkinter как tk

 class PlayerStats:
    def __init__(self, name, touches, shots):
        team = "Barcelona"
        self.name = name
        self.touches = touches
        self.shots = shots

    def count(self, number):
        self.number  = 1
        print(number)

messi = PlayerStats("Messi",0)

root = tk.Tk()
root.bind('<Return>', lambda event :messi.count(messi.touches))
root.bind('<s>', lambda event :messi.count(messi.shots))
root.mainloop()
 

где число представляет либо messi.shots, либо messi.touches в зависимости от того, какая клавиша нажата. Я бы хотел сделать это без воссоздания набора почти идентичных функций для каждой клавиши.