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

Kivy游戏菜单按钮变形、背景留白问题求助

Kivy游戏菜单界面适配问题解答

问题描述

我用Kivy编写了一款游戏的菜单界面,代码如下。原本期望代码能适配1080×1920分辨率,调整图片时不会失真,但运行后背景图左右出现黑边,按钮会显示在黑边区域,调整按钮位置时按钮图片还会变形(注:background.png分辨率同样为1080×1920)。

# Setting the window size and scaling
Config.set('graphics', 'width', '1080')
Config.set('graphics', 'height', '1920')
Window.size = (1080, 1920)

class NineStonesApp(App):
    # Defining the attributes of the class
    def __init__(self, **kwargs):
        # Inheriting the attributes of the App class
        super(NineStonesApp, self).__init__(**kwargs)
        # Setting the window size to 1080x1920
        Window.size = (1080, 1920)
        # Creating a screen manager
        self.screen_manager = ScreenManager()
        # Creating the menu and game screens
        self.menu_screen = MenuScreen(name="menu")
        self.game_screen = GameScreen(name="game")
        # Adding the screens to the screen manager
        self.screen_manager.add_widget(self.menu_screen)
        self.screen_manager.add_widget(self.game_screen)

# Defining the function that will run when the app starts
    def build(self):
        # Returning the screen manager
        print("build Function is Running")
        return self.screen_manager

class MenuScreen(Screen):
    # Defining the attributes of the class
    def __init__(self, **kwargs):
        # Inheriting the attributes of the Screen class
        super(MenuScreen, self).__init__(**kwargs)
        
# Creating an image that shows the background of the menu screen
        self.background = Image(source="images/background.png", pos=(0, 0), size=(1080, 1920))
        
# Creating a button for single player game selection
        self.single_button = Button(background_normal="images/single.png", background_down="images/single.png", pos=(150, 500), size=(100, 100), size_hint=(None, None))

        # Binding a function to start the single player game when the button is pressed
        self.single_button.bind(on_press=self.start_single)
        
# Creating a button for double player game selection
        self.double_button = Button(background_normal="images/double.png", background_down="images/double.png", pos=(300, 500), size=(150, 150), size_hint=(None, None))
        # Binding a function to start the double player game when the button is pressed
        self.double_button.bind(on_press=self.start_double)
       
 # Creating a button for online game selection
        self.online_button = Button(background_normal="images/online.png", background_down="images/online.png", pos=(450, 500), size=(200, 200), size_hint=(None, None))
        # Binding a function to start the online game when the button is pressed
        self.online_button.bind(on_press=self.start_online)
       
 # Adding the background image to the screen
        self.add_widget(self.background)
        
# Adding the buttons to the screen
        self.add_widget(self.single_button)
        self.add_widget(self.double_button)
        self.add_widget(self.online_button)
        print("Menuscreen Function is Running")

问题原因

  1. 系统缩放干扰窗口渲染:你手动设置了窗口大小,但Kivy会默认跟随系统的显示缩放比例(比如Windows的125%缩放)调整实际渲染尺寸,导致窗口实际显示大小和你设置的1080×1920不匹配,背景图无法填满窗口,出现黑边。
  2. 背景图未设置自适应属性:你给背景图固定了size=(1080,1920),但没开启自适应拉伸或保持比例的属性,当窗口实际尺寸变化时,图片无法自动适配,要么留黑边要么变形。
  3. 按钮定位与尺寸匹配问题:按钮用固定pos定位,当窗口实际显示区域变化时,按钮就会跑到黑边区域;另外如果按钮设置的size和背景图本身的比例不一致,Kivy默认会拉伸图片填充按钮,导致变形。

解决方法

1. 强制窗口按设定分辨率渲染

在代码最开头添加配置,禁用系统缩放干扰,确保Kivy严格按1080×1920渲染:

from kivy.config import Config
# 必须放在所有Kivy其他模块导入之前
Config.set('graphics', 'width', '1080')
Config.set('graphics', 'height', '1920')
Config.set('graphics', 'resizable', '0')  # 禁止窗口手动调整大小
Config.set('graphics', 'scale', '1')  # 强制缩放比例为1,不受系统缩放影响
Config.set('graphics', 'window_state', 'normal')  # 保持窗口为设定大小,也可设为'fullscreen'全屏

2. 让背景图自适应窗口且不失真

修改背景图的Image控件属性,让它自动占满屏幕并保持比例:

self.background = Image(
    source="images/background.png",
    pos_hint={'x': 0, 'y': 0},
    size_hint=(1, 1),  # 占满整个Screen的宽高
    allow_stretch=True,  # 允许拉伸适配
    keep_ratio=True  # 保持原图比例,避免失真;如果要完全填满窗口可设为False
)

3. 按钮避免变形+自适应定位

  • 保证按钮尺寸与背景图比例一致:比如按钮设size=(100,100),那对应的按钮图片(single.png等)也要是1:1的分辨率,这样不会被拉伸变形。
  • 用相对定位替代固定位置:用pos_hint设置按钮的相对位置,确保不管窗口怎么变,按钮都在合理区域:
self.single_button = Button(
    background_normal="images/single.png",
    background_down="images/single.png",
    size=(100, 100),
    size_hint=(None, None),
    pos_hint={'center_x': 0.2, 'y': 0.1}  # center_x是屏幕宽度的20%位置,y是底部10%位置
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:37:06