#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: Имя виджета не может начинаться с заглавной буквы.