我对面向对象编程的理解有点不稳定,所以如果你有任何有助于解释这些概念的链接,那么看它们会很棒!
我稍微缩短了代码。基本原则是我有一个以Controller主类实例开头的游戏。打开游戏时,将打开Popup类。事件发生如下:
我的问题在于第3步。我得到的错误信息是:
TypeError: unbound method start_game() must be called with Controller
instance as first argument (got nothing instead)
我想在StartPopUp类中需要对Controller类进行一些引用。但我不太明白如何创建该引用?
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()
提前致谢!
答案 0 :(得分:2)
您可以像这样传递实例
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()
答案 1 :(得分:1)
您需要在start_game()
课程的实例上调用Controller
。例如,
def start_click(self):
controller = Controller()
controller.start_game()
这样,startgame()
的{{1}}参数将指向self
对象。但是,您需要跟踪创建的controller
实例,以便以后能够再次修改它。在这种情况下,没有理由将Controller
作为静态变量。
你可能想要的是一个静态方法,可以在不必拥有playing_label
类的实例的情况下调用它。为此,您可以使用staticmethod
decorator使Controller
成为静态方法,如下所示:
start_game()
然后,您可以继续使用@staticmethod
def start_game():
Controller.playing_label = True
print Controller.playing_label
。
答案 2 :(得分:1)
从错误消息中可以明显看出,必须为控制器类的特定实例调用方法start_game()
。您可以为控制器类添加getInstance()
方法,该方法返回控制器的当前活动实例。在调用start_click()
之前,从start_game()
方法中调用此方法。假设它返回instanceC
。然后,您可以start_game()
将instanceC.start_game()
方法称为start_click()
。
答案 3 :(得分:1)
尝试在创建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