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

Kivy自定义Popup缩放异常:控件点击错位及背景透明

Kivy自定义Popup缩放后背景透明、点击区域错位的解决方法

你遇到的问题根源在于:Canvas的Scale指令只修改绘制效果,不改变Widget的物理边界和布局逻辑。具体来说:

  • 背景透明:Popup的默认背景属于其内部的基础布局,没有被包含在你自定义的canvas缩放范围内,导致背景没被渲染。
  • 点击区域错位:Kivy的输入事件检测依赖Widget的实际pos和size,你只是缩放了绘制内容,组件的物理点击区域还是原始的大尺寸和位置。

下面是两种可行的解决办法:

方法一:直接调整尺寸实现缩放(推荐)

删掉canvas的PushMatrix/Scale/PopMatrix代码,直接把Popup和内部组件的尺寸都缩小0.5倍,同时保持居中:

<CustomPopup@Popup>:
    id: configure_popup
    title: "Configure Server Settings"  # 弹窗标题
    size_hint: None, None
    # 原始尺寸缩小0.5倍
    size: dp(600)*0.5, dp(320)*0.5
    # 保持屏幕居中
    pos_hint: {'center_x': 0.5, 'center_y': 0.5}
    
    GridLayout:
        cols: 1
        # 内部间距同步缩小
        padding: dp(10)*0.5
        spacing: dp(10)*0.5
        
        TextInput:
            id: server_url
            hint_text: 'Server URL'
            multiline: True
            size_hint_y: None
            height: dp(40)*0.5

        TextInput:
            id: api_key
            hint_text: 'Api Key'
            multiline: False
            size_hint_y: None
            height: dp(40)*0.5

        Label:
            text: "请妥善保管此密钥:它可访问你的所有数据。你可以在网页应用的个人资料中获取该密钥"
            color: 0.5, 0.5, 0.5, 1
            italic: True
            size_hint_y: None
            height: self.texture_size[1]*0.5
            text_size: self.width, None 

        Button:
            text: "保存并关闭窗口"
            size_hint_y: None
            height: dp(40)*0.5
            on_release: configure_popup.save_and_close()
        
        Button:
            id: test_conifg_button
            text: "测试服务器配置"
            size_hint_y: None
            height: dp(40)*0.5
            on_release: app.test_server_configuration(server_url.text, api_key.text, self)

这种方式让组件的物理尺寸和显示效果完全匹配,既解决了点击错位,也能正常显示Popup背景。

方法二:用Scatter组件包裹内容(保留原始尺寸)

如果不想修改内部组件的dp参数,可以用Scatter来处理缩放和输入事件转换:

<CustomPopup@Popup>:
    id: configure_popup
    title: "Configure Server Settings"
    size_hint: None, None
    # Popup物理尺寸设为缩放后的大小,确保背景正常显示
    size: dp(600)*0.5, dp(320)*0.5
    pos_hint: {'center_x': 0.5, 'center_y': 0.5}
    
    Scatter:
        # 内容保持原始尺寸
        size: dp(600), dp(320)
        scale: 0.5
        pos_hint: {'center_x': 0.5, 'center_y': 0.5}
        do_translation: False  # 禁止拖动内容
        
        GridLayout:
            cols: 1
            padding: dp(10)
            spacing: dp(10)
            size: dp(600), dp(320)  # 和Scatter尺寸一致
            
            TextInput:
                id: server_url
                hint_text: 'Server URL'
                multiline: True
                size_hint_y: None
                height: dp(40)

            TextInput:
                id: api_key
                hint_text: 'Api Key'
                multiline: False
                size_hint_y: None
                height: dp(40)

            Label:
                text: "请妥善保管此密钥:它可访问你的所有数据。你可以在网页应用的个人资料中获取该密钥"
                color: 0.5, 0.5, 0.5, 1
                italic: True
                size_hint_y: None
                height: self.texture_size[1]
                text_size: self.width, None 

            Button:
                text: "保存并关闭窗口"
                size_hint_y: None
                height: dp(40)
                on_release: configure_popup.save_and_close()
            
            Button:
                id: test_conifg_button
                text: "测试服务器配置"
                size_hint_y: None
                height: dp(40)
                on_release: app.test_server_configuration(server_url.text, api_key.text, self)

Scatter会自动将输入事件转换为缩放后的坐标,确保点击位置和显示位置对应,同时Popup的背景会根据设置的物理尺寸正常渲染。

内容的提问来源于stack exchange,提问作者Ibtsam Ahmad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 22:05:53