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

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

#python #python-3.x #ооп #tkinter

Вопрос:

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

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

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

 from tkinter import *
Root = Tk()

PlrWeapon = ["Pipe Revolver Rifle",6,5,0]

class Raider:
    Species = "Human"
    def __init__(self, Name, Level, MaxHealth, Health, Alive, Unique, Weapon, Armour):
        self.Name = Name
        self.Level = Level
        self.MaxHealth = MaxHealth
        self.Health = Health
        self.Alive = Alive
        self.Unique = Unique
        self.Weapon = Weapon
        self.Armour = Armour

def Shoot(self):
    Damage = 0
    for i in range(1,4):
        Difference = PlrWeapon[i] - self.Armour[i]
        if Difference >= 0:
            Damage = Damage   Difference
    self.Health = self.Health - Damage
    if self.Health <= 0:
        self.Alive = False

Enemy1 = Raider("Tessa",
                5,
                50,
                50,
                True,
                False,
                ["Pipe Pistol",3,2,0],
                ["Armourless",0,0,0])

Enemy2 = Raider("Bobby",
                5,
                50,
                50,
                True,
                False,
                ["Pipe Rifle",5,4,0],
                ["Leather",2,3,1])

Shoot(Enemy1)

Enemy1Name = Label(Root, text=Enemy1.Name)
Enemy1Name.grid(row=0, column=0)
Enemy1Health = Label(Root, text=Enemy1.Health)
Enemy1Health.grid(row=0, column=1)

Enemy2Name = Label(Root, text=Enemy2.Name)
Enemy2Name.grid(row=1, column=0)
Enemy2Health = Label(Root, text=Enemy2.Health)
Enemy2Health.grid(row=1, column=1)

Root.mainloop()
  

в идеале в конце Shoot() процедуры должна быть часть, которая действовала бы следующим образом

 def Shoot(self):
    Damage = 0
    for i in range(1,4):
        Difference = PlrWeapon[i] - self.Armour[i]
        if Difference >= 0:
            Damage = Damage   Difference
    self.Health = self.Health - Damage
    if self.Health <= 0:
        self.Alive = False

    ## start of wishful thinking ##

    str(self) "Health".config(text=self.Health)
  

Если вы понимаете, что я пытаюсь сообщить, и у вас есть решение, я был бы очень признателен за помощь. Спасибо.

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

1. «Я просто не знаю, как настроить таргетинг на правильный виджет label в конце». Не могли бы вы, пожалуйста, объяснить, что вы имеете в виду под этим? Я понимаю все остальное, просто это утверждение немного сбивает с толку. Кроме того, что такое fallout? Это игра? Я новичок в играх, поэтому простите меня за этот вопрос.

Ответ №1:

Если я вас правильно понял, вы хотите изменить метку работоспособности, связанную с Raider объектом, переданным Shoot методу.

Вот решение, которое может сработать, но я не уверен, что это рекомендуемый способ, поскольку вы должны быть очень осторожны.

 def Shoot(self, win):
    Damage = 0
    for i in range(1,4):
        Difference = PlrWeapon[i] - self.Armour[i]
        if Difference >= 0:
            Damage = Damage   Difference
    self.Health = self.Health - Damage
    if self.Health <= 0:
        self.Alive = False
    win.nametowidget('.health{}'.format(self.Name)).config(text=self.Health)

Enemy1Name = Label(Root, text=Enemy1.Name, name='name' Enemy1.Name)
Enemy1Name.grid(row=0, column=0)
Enemy1Health = Label(Root, text=Enemy1.Health, name='health' Enemy1.Name)
Enemy1Health.grid(row=0, column=1)

Enemy2Name = Label(Root, text=Enemy2.Name, name='name' Enemy2.Name)
Enemy2Name.grid(row=1, column=0)
Enemy2Health = Label(Root, text=Enemy2.Health, name='health' Enemy2.Name)
Enemy2Health.grid(row=1, column=1)
  

Виджеты хранятся в tkinter в виде древовидной структуры, где ваше Tk() окно является корневым, представленным . . Тогда его дочерние элементы будут представлены как .unique_widget1_id и дочерние элементы widget1, подобные .unique_widget1_id.unique_widget2_id . По умолчанию tkinter создает идентификаторы типа, .140343920750152 которые можно увидеть с помощью widget.__str__() метода.

Но вы можете добавлять пользовательские имена к виджетам при их создании, как показано в этом решении (пожалуйста, убедитесь, что у каждого виджета есть уникальное имя, чтобы избежать проблем. Если вы создадите два виджета с одинаковыми именами, то это создаст только первый виджет, а второй будет просто ссылкой на тот же виджет). Затем вы можете вызвать nametowidget() метод в любом виджете / окне и указать относительный / абсолютный путь для получения объекта widget (и выполнять операции над виджетом).

Дайте мне знать, если у вас возникнут вопросы.

PS: Имя виджета не может начинаться с заглавной буквы.