好的,所以我有一个程序,在某些条件下,需要删除一些选项并提供其他选项。我最初设计它是为了使某些按钮占据相同的空间。但是,当触发on_touch_down()
时,我编写的预期开关不会交换布局。
from kivy.uix.widget import Widget
from kivy.config import Config
from kivy import graphics
from kivy.uix.button import Button
from SpotChess import SCBoardWidget
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.relativelayout import RelativeLayout
promote_now = False
class Chessboard(Widget):
def __init__(self, **kwargs):
super(Chessboard, self).__init__(**kwargs)
self.bind(pos=self.drawBoardandPieces)
self.bind(size=self.drawBoardandPieces)
self.drawBoardandPieces()
def drawBoardandPieces(self, *args):
with self.canvas:
# Reset the canvas in case of redraws.
self.canvas.clear()
# Define the lengths of the edges of the squares.
edge_len = min(self.height, self.width) // 8
Config.set("graphics", "resizable", True)
for column in range(0, 8):
for row in range(0, 8):
if ((row + column) % 2) == 0:
graphics.Color(0, 0, 1)
self.dark_rect = graphics.Rectangle(pos=(column*edge_len, row*edge_len),
size=(edge_len, edge_len))
else:
graphics.Color(1, 1, 1)
self.light_rect = graphics.Rectangle(pos=(column*edge_len, row*edge_len),
size=(edge_len, edge_len))
# This provides all of the user's mouse interaction with the board.
def on_touch_down(self, touch):
global promote_now
if promote_now == False:
promote_now = True
Options().swapMenus()
else:
promote_now = False
Options().swapMenus()
game_board = Chessboard()
class PromotionOptions(GridLayout):
def __init__(self, **kwargs):
super(PromotionOptions, self).__init__(**kwargs)
self.cols = 4
self.queen_btn = Button(text="Q/q")
self.rook_btn = Button(text="R/r")
self.bishop_btn = Button(text="B/b")
self.knight_btn = Button(text="N/n")
self.add_widget(self.queen_btn)
self.add_widget(self.rook_btn)
self.add_widget(self.bishop_btn)
self.add_widget(self.knight_btn)
class Options(GridLayout):
def __init__(self, **kwargs):
super(Options, self).__init__(**kwargs)
self.cols = 1
self.swapMenus()
def swapMenus(self):
global promote_now
self.clear_widgets()
if promote_now == False:
# Present the menu layout for normal play.
self.normal_play_menu = GridLayout(cols=3)
# It contains the button to flip the board.
self.flip_board_btn = Button(text="Flip")
self.normal_play_menu.add_widget(self.flip_board_btn)
self.add_widget(self.normal_play_menu)
else:
# Present the menu layout for pawn promotions.
self.promotion_menu = GridLayout(cols=1)
self.promotion_menu.add_widget(widget=PromotionOptions())
self.add_widget(self.promotion_menu)
class SCApp(App):
def build(self):
top_portion = BoxLayout(orientation="vertical")
chessboard_portion = RelativeLayout()
chessboard_portion.add_widget(widget=game_board)
top_portion.add_widget(widget=chessboard_portion)
bottom_portion = BoxLayout(orientation="vertical")
bottom_portion.add_widget(widget=Options())
app_layout = BoxLayout(orientation="vertical")
app_layout.add_widget(top_portion)
app_layout.add_widget(bottom_portion)
return app_layout
SCApp().run()
我显然正在调用该对象来执行替换,但是即使我已经调用了该函数,它也没有完成self.clear_widgets()
或self.add_widget()
。我想念什么?
答案 0 :(得分:1)
在您的on_touch_down()
方法中
Options().swapMenus()
行正在创建Options
类的新实例,并调用该新实例的swapMenus()
方法。但是Options
的新实例不在您的GUI中,因此对您的应用程序没有任何影响。您需要获取GUI中IS的Options
实例的引用,并调用该实例的swapMenus()
方法。
您可以通过在Options
方法中保存对App
类的引用,方法是在build()
方法中替换以下行:
bottom_portion.add_widget(widget=Options())
具有:
self.options = Options()
bottom_portion.add_widget(widget=self.options)
然后使用on_touch_down()
方法:
def on_touch_down(self, touch):
global promote_now
# get the instance of Options that is in the App
options = App.get_running_app().options
if promote_now == False:
promote_now = True
options.swapMenus()
else:
promote_now = False
options.swapMenus()