繁体   English   中英

使用 on_touch_down() 在 Kivy 中交换小部件/替换布局

[英]Swapping Widgets / Replacing Layouts in Kivy With on_touch_down()

好的,所以我有一个程序,在某些条件下,需要删除一些选项并呈现一些其他选项。 我最初设计它是为了让某些按钮占据相同的空间。 但是,当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()

我清楚地调用 object 来执行替换,但它没有完成self.clear_widgets()self.add_widget() ,即使我已经调用了 function。 我错过了什么?

在您的on_touch_down()方法中

Options().swapMenus()

行正在创建Options class 的新实例,并调用该新实例的swapMenus()方法。 但是那个新的Options实例不在你的 GUI 中,所以它对你的应用程序没有影响。 您需要获取 GUI 中的Options实例的引用,并调用该实例的swapMenus()方法。

您可以通过在您的App中保存对Options class 的引用来做到这一点,方法是在您的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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM