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

Python/KivyMD自定义MDDialog中ScrollView上方出现空白区域如何解决

我是StackOverflow以及Python/Kivy开发领域的新手,若有提问不合规的地方还请大家指正。

问题背景

我尝试基于Python/KivyMD封装一个可复用的简易DialogSelector选择器,只需传入选项列表即可弹出对应选择弹窗供用户点击选择。目前功能逻辑运行完全符合预期,但弹出的自定义MDDialog中,ScrollView组件的上方出现了一块多余的空白区域,我暂时找不到该空白区域的产生原因。

对话框效果截图

我清楚存在更优的实现方案,以下是我当前的实现代码:

DialogSelector.py 实现代码

from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd.uix.dialog import MDDialog
from kivymd.uix.list import OneLineListItem
from kivymd.uix.button import MDFlatButton


Builder.load_string( """
<CustomDLG>
    orientation: "vertical"
    spacing: "12dp"
    size_hint_y: None
    height: "200dp"
    pos_hint: { "top": 1 }

    ScrollView:
        id: scView
        
        MDList:
            id: itemList
""" )


class CustomDLG( BoxLayout ):
    pass


class DialogSelector():

    def __init__( self, title, items, callback ):
        self.items = items
        self.title = title
        self.callback = callback
        self.dialog = None
        self.displayed = None
        self.keyword = None

    def open(self, *args):
        if not self.dialog:
            self.dialog = MDDialog(
                title=self.title,
                type="custom",
                size_hint=(.8, .7),
                content_cls=CustomDLG(),
                buttons=[ MDFlatButton( text="Abbrechen",  on_release=self.close ) ]
            )

        self.dialog.content_cls.ids.itemList.clear_widgets()
        for entry in self.items:
            if type(entry) is str: entry = { "Keyword": entry, "Displayed": entry }
            if type(entry) is dict:
                if "Keyword" in entry and "Displayed" in entry:
                    self.dialog.content_cls.ids.itemList.add_widget( 
                        OneLineListItem( id=str(entry["Keyword"]), text=str(entry["Displayed"]), on_release=self.itemSelected ) 
                    )

        self.dialog.open()


    def close(self, *args):
        self.dialog.dismiss( force=True )


    def itemSelected(self, item):
        self.displayed = item.text
        self.keyword = item.id
        if self.dialog: self.dialog.dismiss( force=True )
        self.callback( self )

调用示例(其他.py文件中)

from CustomWidgets.DialogSelector import DialogSelector

def openCategoryDialog(self):
    self.dialog = DialogSelector( 
        title = "Kategorie wählen", 
        items = [{"Keyword":"A", "Displayed":"ABCDE"},{"Keyword":"B", "Displayed":"BEDF"}], 
        callback = self.categorySelected 
        )
    self.dialog.open()

def categorySelected(self, dlg):
    print( dlg.keyword )
    print( dlg.displayed )

解决方案

顶部空白由两个默认配置共同导致,做如下两处修改即可消除:

  1. 修改KV规则,移除无用的spacing配置,同时取消MDList默认的顶部内边距:
<CustomDLG>
    orientation: "vertical"
    size_hint_y: None
    height: "200dp"

    ScrollView:
        id: scView
        
        MDList:
            id: itemList
            padding: 0, 0, 0, 0
  1. 初始化MDDialog时添加content_padding参数,移除内容区域的默认内边距:
self.dialog = MDDialog(
    title=self.title,
    type="custom",
    size_hint=(.8, .7),
    content_cls=CustomDLG(),
    content_padding=(0, 0, 0, 0),
    buttons=[ MDFlatButton( text="Abbrechen",  on_release=self.close ) ]
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 07:54:02