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

Kivy中Canvas背景图片偏移问题技术求助(附代码)

Kivy GridLayout背景图片偏移问题解决

问题分析

你遇到的图片偏移,核心原因有两个:

  1. 创建card1后立刻设置Canvas元素时,控件还未被添加到父容器,此时的size和pos是初始值,不是最终布局后的实际坐标;
  2. 直接赋值静态的card1.size和card1.pos,不会随控件布局更新而自动同步。

修复方案

方案1:将背景图片逻辑移到KV文件(推荐)

把背景图片的绘制整合到CardGL的KV定义中,Kivy会自动帮你绑定控件的size和pos,确保图片始终与控件对齐:

修改KV代码:

<CardGL@GridLayout>:
    background_color: 1,1,1,0
    canvas.before:
        Color:
            rgb: kivy.utils.get_color_from_hex('#000000')
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [10,10,10,10]
        BoxShadow:
            pos: self.pos
            size: self.size
            offset: 5, -5
            spread_radius: -7, -7
            border_radius: [10,10,10,10]
            blur_radius: 10
    # 新增背景图片绘制(放到canvas.after确保在阴影和边框之上)
    canvas.after:
        Color:
            rgb: 1,1,1,1  # 必须设置不透明颜色,否则图片会被隐藏
        RoundedRectangle:
            source: GS_IMG_LSRC  # 替换为你的图片路径
            size: self.size
            pos: self.pos
            radius: [10,10,10,10]
    canvas:
        Color:
            rgb: 1,1,1,0
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [10,10,10,10]
    cols: 1
    size: dp(Factory.WinCalcs.LB_LTW * .36), dp(Factory.WinCalcs.GL_LTH_C * .6)
    size_hint: None, None
    padding: dp(0),dp(0)

然后Python代码里删除手动添加Canvas的部分,直接创建card1即可:

card1 = Factory.CardGL()
sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN').ids.DB_MAIN_BL_T_01.add_widget(card1)
# 后续代码不变...

方案2:在Python中动态绑定属性

如果必须在Python代码中添加背景图片,需要将RoundedRectangle的size和pos与card1的属性绑定,确保布局变化时自动更新:

修改Python代码:

card1 = Factory.CardGL()
# 创建背景矩形并绑定控件的size和pos
bg_rect = RoundedRectangle(source=GS_IMG_LSRC, radius=[10,10,10,10])
# 绑定属性,确保矩形随控件尺寸/位置变化
bg_rect.bind(size=card1.setter('size'), pos=card1.setter('pos'))
# 添加到canvas的合适层级(比如canvas.after避免被阴影覆盖)
card1.canvas.after.add(bg_rect)

# 后续添加代码不变
sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN').ids.DB_MAIN_BL_T_01.add_widget(card1)
sm.get_screen('sm3').ids.Dashboard_SM_1.get_screen('DB_MAIN').ids['card_1'] = weakref.ref(card1)
# ...其他代码

额外注意事项

  • 确保Color指令的rgb或rgba值不是全透明(比如1,1,1,0),否则图片会无法显示;
  • 根据需求选择Canvas层级:canvas.before会在子控件之前绘制,canvas.after会在子控件之后绘制,避免图片被遮挡;
  • 如果后续给CardGL添加了padding,需要调整矩形的pos和size,比如pos: self.pos + self.padding、size: self.size - self.padding*2。

内容的提问来源于stack exchange,提问作者Manic Lyndon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:17:16