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

Kivy中GridLayout布局无法自适应全屏大小的问题求助

Kivy GridLayout无法调整大小适配全屏问题

您好,我遇到了GridLayout无法调整大小适配全屏的问题:图中红色线条标注的是Kivy识别的窗口边界位置。
我的实现思路如下:
我创建了1列的GridLayout作为承载所有组件的基础布局,首先将顶部栏(3列GridLayout,放置功能按钮)添加到基础层,之后创建可滚动区域也添加到基础层,以此实现顶部栏固定在屏幕顶部、不随滚动位移的效果。
但运行后发现我的基础层没有拉伸占满应用的全部可用空间。
测试时可使用任意PNG替代开发用到的PNG文件。
红色线条为截断位置

补充说明

该问题可能和GridLayout误以为内部还有其他待放置元素有关:我在下方添加更多PDF作为新行时,新内容恰好从图中红色线条位置开始渲染,请问问题出在哪里?


问题原因

代码里的布局参数设置错误导致了这个问题,核心错误点如下:

  • 根布局InfoPage的size_hint设置为(0.9, 0.9),直接限定了它只占父容器90%的宽高,不可能满屏显示
  • 根布局InfoPage绑定了minimum_height = self.setter('height'),这个绑定是滚动容器内的子布局才需要的设置,目的是让子布局高度随内容撑开,根布局需要占满整个屏幕,不需要跟随内容高度变化
  • 用来承载顶部栏和滚动区域的base_layout设置了size_hint_y=None同时绑定了minimum_height,这会让它的高度只等于子控件总高度,不会自适应拉伸占满根布局的剩余空间
  • ScrollView的size_hint_y设置为None还写死了高度为Window.height,不仅会导致滚动区域超出屏幕,还无法适配窗口大小变化
修正方案

只需要调整这几个布局的参数即可:

  1. 将InfoPage的size_hint改为(1, 1),删除minimum_height绑定
  2. 将base_layout的size_hint改为(1,1),删除minimum_height绑定
  3. 将ScrollView的size_hint改为(1, 0.9),删除写死的size参数,让它自动占满顶部栏之外的剩余空间
  4. 顶部栏的Button的size_hint_y设置为1,不要写死为0.2,否则按钮不会适配顶部栏高度

修正后可运行代码

from kivy.app import App
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.scrollview import ScrollView
from kivy.uix.boxlayout import BoxLayout
import pandas as pd
     
class InfoPage(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.cols = 1
        # 修改:占满父容器全部空间
        self.size_hint = (1,1)
        self.spacing = 10
        # 删除不需要的minimum_height绑定
        
    #Base Layout
        # 修改:占满根布局全部空间,不需要根据内容自适应高度
        self.base_layout = GridLayout(size_hint=(1,1), cols=1, spacing=20)
        # 删除不需要的minimum_height绑定
        
#Top Bar with Buttons "1", "2" & "3"
        self.top_bar_layout = BoxLayout(orientation="horizontal", size_hint=(1, .1), spacing=10)
        self.back_to_mainpage = (Button(text= "Back to MainPage",
                                size_hint = (1,1),
                                bold = True,
                                background_color = '#00FFCE',
                             ))
        
        self.top_bar_layout.add_widget(self.back_to_mainpage)
        self.top_bar_layout.add_widget(Button(text= "Button 2",
                             size_hint = (1,1),
                             bold = True,
                             background_color = '#00FFCE'))
        self.top_bar_layout.add_widget(Button(text= "Button 3",
                             size_hint = (1,1),
                             bold = True,
                             background_color = '#00FFCE'))

#Scroll View Base Layout
        self.scroll_view_base_layout = GridLayout(cols=1, size_hint_y=None)
        self.scroll_view_base_layout.bind(minimum_height = self.scroll_view_base_layout.setter('height'))

#Scrollable Content

    #Label Grid
        self.content_scroll_view_top_label = GridLayout(size_hint_y = None, row_default_height=80, cols=2)
        self.content_scroll_view_top_label.bind(minimum_height=self.content_scroll_view_top_label.setter('height'))
        
        self.content_scroll_view_top_label.add_widget(Label( 
                text= "Avalanche \n \n Profile:",
                font_size = 20,
                color='00FFCE',
                size_hint = (0.5,1),
                halign="center",
                valign="middle",
                ))
        self.content_scroll_view_top_label.add_widget(Label( 
                text= "Weather \n \n Data (Past):",
                font_size = 20,
                color='00FFCE',
                size_hint = (0.5,1),
                halign="center",
                valign="middle",
                ))
        
    #Png Grid
        self.content_scroll_view_top_png = GridLayout(size_hint_y=None, row_default_height=1000, cols=2)
        self.content_scroll_view_top_png.bind(minimum_height=self.content_scroll_view_top_png.setter('height'))
        
        self.content_scroll_view_top_png.add_widget(Image(source="Data_files\Changing_Data\Outputs\snowprofile_15444-1.png"))
        self.content_scroll_view_top_png.add_widget(Image(source="Data_files\Changing_Data\Outputs\Arlingsattel.png"))

    #Weather Data Grid
        self.weather_data_grid = GridLayout(size_hint=(1,None), row_default_height=15, cols=16)
        self.weather_data_grid.bind(minimum_height = self.weather_data_grid.setter('height'))
        #Heading row description
        self.weather_data_grid.add_widget(Label(text='Clouds'))
        self.weather_data_grid.add_widget(Label(text='Cloud Cover Type'))
        self.weather_data_grid.add_widget(Label(text='Icons'))
        self.weather_data_grid.add_widget(Label(text='Precipication %'))
        self.weather_data_grid.add_widget(Label(text='Time'))
        self.weather_data_grid.add_widget(Label(text='Temperature'))
        self.weather_data_grid.add_widget(Label(text='Fells like Temperature'))
        self.weather_data_grid.add_widget(Label(text='Air Pressure'))
        self.weather_data_grid.add_widget(Label(text='Humidity'))
        self.weather_data_grid.add_widget(Label(text='Dew Point'))
        self.weather_data_grid.add_widget(Label(text='UV Index'))
        self.weather_data_grid.add_widget(Label(text='Cloud Coverage %'))
        self.weather_data_grid.add_widget(Label(text='Visibility'))
        self.weather_data_grid.add_widget(Label(text='Wind Speed'))
        self.weather_data_grid.add_widget(Label(text='Wind Direction'))
        self.weather_data_grid.add_widget(Label(text='Wind Gusts'))
        #Row 1
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
        self.weather_data_grid.add_widget(Label(text='test'))
  

#Add Content to Scrollable space
        self.scroll_view_base_layout.add_widget(self.content_scroll_view_top_label)
        self.scroll_view_base_layout.add_widget(self.content_scroll_view_top_png)
        self.scroll_view_base_layout.add_widget(self.weather_data_grid)

#Create scrollview
        # 修改:不写死尺寸,自适应剩余空间
        self.scrollview = ScrollView(size_hint=(1, 0.9))
        #add layout to scrollview
        self.scrollview.add_widget(self.scroll_view_base_layout)
    
#Add Widgets to Base Layout
        self.base_layout.add_widget(self.top_bar_layout)
        self.base_layout.add_widget(self.scrollview)      

#Add Base Layout to Window
        self.add_widget(self.base_layout)
        

class SkitouringApp(App):
    def build(self):
        self.screen_manager = ScreenManager()
        
        self.info_page = InfoPage()
        screen = Screen(name="Info")
        screen.add_widget(self.info_page)
        self.screen_manager.add_widget(screen)
        
        return self.screen_manager
    
if __name__ == "__main__":
    Skitour_app = SkitouringApp()
    Skitour_app.run()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:06:03