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

Kivy自定义RoundedTextInput组件Canvas元素无法显示问题

实现错误点说明

你的代码有4个核心问题,导致自定义Canvas内容无法正常显示:

  • 坐标取值时机错误:__init__方法执行时控件还未完成布局计算,此时读取的self.pos、self.size都是初始默认占位值,不是控件实际显示的位置和尺寸。并且你没有做位置、尺寸的更新绑定,后续控件完成布局后,绘制的图形还停留在初始坐标,自然无法显示在正确位置。
  • 语法拼写错误:定义左侧圆角的Ellipse时,参数错写为ange_start=180,正确参数名是angle_start,漏写字母l会导致该图形指令直接报错失效。
  • 绘制逻辑冗余冲突:你同时使用填充类型的Ellipse和描边类型的Line绘制圆角,蓝色填充的半圆会直接覆盖输入区域和边框;另外你在canvas.before层只设置了纯黑不透明的颜色,没有绘制任何实际图形,属于无效代码,还可能干扰画布的颜色状态。
  • 旧示例兼容性问题:你复制的公开示例是基于早期Kivy版本编写的,Kivy 2.0及以上版本调整了TextInput的默认背景绘制逻辑和Canvas层级,旧代码的自定义绘制内容会被默认背景遮挡,同时旧代码绑定的更新属性在新版本中不生效,因此运行后只显示空白窗口。
正确实现方式

核心调整点:

  1. 不要在__init__中硬编码图形坐标,将图形的位置、尺寸绑定到控件的pos、size属性,控件布局变化时自动重绘
  2. 直接使用Kivy内置的RoundedRectangle绘制圆角背景和描边,不需要手动拼接半圆和直线,减少出错概率
  3. 给控件设置左右内边距,避免输入文本被圆角边框遮挡

修复后的可运行代码:

from kivy.graphics import Color, Line, RoundedRectangle
from kivy.uix.textinput import TextInput

class RoundedTextInput(TextInput):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.multiline = False
        # 隐藏原生默认背景
        self.background_color = (0, 0, 0, 0)
        self.cursor_color = (0, 0, 0, 1)
        # 配置边框和圆角参数
        self.border_width = 2
        self.corner_radius = self.height / 2 if self.height else 20
        # 设置文本内边距,避免贴边
        self.padding_x = 15

        with self.canvas.before:
            # 绘制白色圆角背景
            self.bg_color = Color(rgba=(1, 1, 1, 1))
            self.bg = RoundedRectangle(
                pos=self.pos,
                size=self.size,
                radius=[self.corner_radius,]
            )
            # 绘制黑色边框
            self.border_color = Color(rgba=(0, 0, 0, 1))
            self.border = Line(
                rounded_rectangle=(*self.pos, *self.size, self.corner_radius),
                width=self.border_width
            )
        
        # 绑定位置、尺寸变化事件,自动更新绘制内容
        self.bind(pos=self._refresh_canvas, size=self._refresh_canvas)

    def _refresh_canvas(self, *args):
        # 随控件高度自动调整圆角半径,实现胶囊形效果
        self.corner_radius = self.height / 2
        # 更新背景参数
        self.bg.pos = self.pos
        self.bg.size = self.size
        self.bg.radius = [self.corner_radius,]
        # 更新边框参数
        self.border.rounded_rectangle = (*self.pos, *self.size, self.corner_radius)

内容的提问来源于stack exchange,提问作者Tobias K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:00:58