Вызов метода из существующего экземпляра
Мое понимание объектно-ориентированного программирования немного шаткое, поэтому, если у вас есть какие-либо ссылки, которые помогут объяснить концепции, было бы здорово их увидеть!
Я несколько сократил код. Основной принцип заключается в том, что у меня есть игра, которая начинается с экземпляра класса main Controller. При открытии игры открывается всплывающий класс. События происходят следующим образом:
- кнопка запуска во всплывающем окне нажата
- метод start_click() работает
- , который вызывает метод start_game() в экземпляре контроллера
- что в свою очередь изменяет состояние игры на 'True' в исходном экземпляре контроллера
Моя проблема связана с шагом 3. Я получаю сообщение об ошибке:
TypeError: unbound method start_game() must be called with Controller
instance as first argument (got nothing instead)
Я думаю, что должна быть какая-то ссылка на класс контроллера в классе StartPopUp. Но я не совсем понимаю, как создать эту ссылку?
import kivy
kivy.require('1.8.0')
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.clock import Clock
from kivy.properties import BooleanProperty, NumericProperty, ObjectProperty
from kivy.uix.popup import Popup
from kivy.lang import Builder
Builder.load_string('''
<StartPopUp>
size_hint: .2, .2
auto_dismiss: False
title: 'Welcome'
Button:
text: 'Play'
on_press: root.start_click()
on_press: root.dismiss()
''')
class StartPopUp(Popup):
def __init__(self, **kw):
super(StartPopUp, self).__init__(**kw)
def start_click(self):
Controller.start_game()
class Controller(Widget):
playing_label = BooleanProperty(False) #Intitial phase of game is off
def __init__(self, **kw):
super(Controller, self).__init__(**kw)
def start_popup(self, dt):
sp = StartPopUp()
sp.open()
def start_game(self):
self.playing_label = True
print self.playing_label
class MoleHuntApp(App):
def build(self):
game = Controller()
Clock.schedule_once(game.start_popup, 1)
return game
if __name__ == '__main__':
MoleHuntApp().run()
Заранее спасибо!
4 ответа:
Вы можете передать экземпляр следующим образом
class StartPopUp(Popup): def __init__(self, controller, **kw): super(StartPopUp, self).__init__(**kw) self.controller = controller def start_click(self): self.controller.start_game()
И в контроллере
def start_popup(self, dt): sp = StartPopUp(self) sp.open()
Необходимо вызвать
start_game()
на экземпляре классаController
. Например,def start_click(self): controller = Controller() controller.start_game()
Таким образом, Аргумент
То, что вы, вероятно, хотите иметь, - это статический метод, который можно просто вызвать, не имея экземпляра классаstartgame()
self
будет указывать на объектcontroller
. Но затем вам нужно отслеживать созданный экземплярController
, чтобы иметь возможность позже изменить его снова. В этом случае нет никакой причины иметьplaying_label
в качестве статической переменной.Controller
. Для этого вы можете сделатьstart_game()
статическим методом с использованиемstaticmethod
декоратор Вот так:@staticmethod def start_game(): Controller.playing_label = True print Controller.playing_label
Затем вы можете продолжить использовать
Controller.start_game()
.
Как видно из сообщения об ошибке, метод
start_game()
должен быть вызван для конкретного экземпляра класса контроллера. Вы можете добавить методgetInstance()
для класса контроллера, который возвращает текущий активный экземпляр контроллера. Вызовите это из Методаstart_click()
перед вызовом методаstart_game()
. Скажем, он возвращаетсяinstanceC
. Тогда вы можете вызвать методstart_game()
какinstanceC.start_game()
изstart_click()
.
Попробуйте передать игровой объект в тот момент, когда вы создаете объект StartPopUp и делаете StartPopUp, чтобы сохранить ссылку на него, поэтому вы можете использовать этот экземпляр позже для метода start_click (), например:
class StartPopUp(Popup): def __init__(self, game_ctrl, **kw): super(StartPopUp, self).__init__(**kw) self.game_ctrl = game_ctrl def start_click(self): self.game_ctrl.start_game() class Controller(Widget): playing_label = BooleanProperty(False) #Intitial phase of game is off def __init__(self, **kw): super(Controller, self).__init__(**kw) def start_popup(self, dt): sp = StartPopUp(self) sp.open() def start_game(self): self.playing_label = True print self.playing_label