You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Kivy自定义Chessboard小部件正常显示在Splitter分割器中

问题原因

你的代码存在两个核心问题导致自定义部件无法在Splitter中正常显示:

  • 基类选择错误:ChessBoardWidget继承自基础Widget类,该类本身没有自动布局能力,不会主动处理子部件的size_hint配置,也不会响应父容器的尺寸变化适配自身大小。你注释中提到的FloatLayout才是适合的基类,布局类会自动管理子部件的尺寸和位置。
  • 静态参数未更新:你在__init__方法中一次性给背景矩形、内部Image设置了size和pos,后续Splitter拖动调整尺寸时,这些参数不会自动同步更新,导致部件显示错位、不可见。
修改方案

调整ChessBoardWidget的实现,更换基类并添加尺寸变化绑定即可:

import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.splitter import Splitter
from kivy.graphics import Color, Rectangle
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout # 导入FloatLayout

kivy.require('2.0.0')

class ChessBoardWidget(FloatLayout): # 更换基类为FloatLayout
    def __init__(self, **kwargs):
        super(ChessBoardWidget, self).__init__(**kwargs)

        with self.canvas.before:
            Color(0, 1, 0, 1)
            self.rect = Rectangle(size=self.size, pos=self.pos)
        # 绑定尺寸、位置变化事件,同步更新背景矩形
        self.bind(size=self._update_rect, pos=self._update_rect)

        self.add_widget(
            Image(source="./data/images/chess-pieces/DarkerGreenGreyChessBoard.png",
                  size_hint=(1, 1), keep_ratio=True, allow_stretch=True))
    
    def _update_rect(self, instance, value):
        self.rect.pos = self.pos
        self.rect.size = self.size


class SplitterGui(BoxLayout):
    def __init__(self, **kwargs):
        super(SplitterGui, self).__init__(**kwargs)
        self.orientation = 'horizontal'

        split1_boxlayout = BoxLayout(orientation='vertical')
        split1 = Splitter(sizable_from='bottom', min_size=100, max_size=1000)
        chessboard_widget = ChessBoardWidget()
        s3_button = Button(text='s3', size_hint=(1, 1))
        split1.add_widget(chessboard_widget)
        split1_boxlayout.add_widget(split1)
        split1_boxlayout.add_widget(s3_button)
        self.add_widget(split1_boxlayout)

        split2 = Splitter(sizable_from='left', min_size=100, max_size=1000)
        s2_button = Button(text='s2', size_hint=(.1, 1))
        split2.add_widget(s2_button)
        self.add_widget(split2)


class SplitterTestApp(App):
    def build(self):
        return SplitterGui()


if __name__ == '__main__':
    SplitterTestApp().run()

修改后自定义部件就能和原来的Button一样,正常在Splitter中显示,拖动分割条也能自适应尺寸调整。

内容的提问来源于stack exchange,提问作者Sam Quintanar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 11:06:01