如何使浮动布局在 kivymd 中具有滚动视图?

Posted

技术标签:

【中文标题】如何使浮动布局在 kivymd 中具有滚动视图?【英文标题】:How can I make a floatlayout have a scrollview in kivymd? 【发布时间】:2021-04-19 08:53:44 【问题描述】:

我正在使用 python 进行一个项目,我需要我的主页是可滚动的,但它不起作用......我已经尝试了几乎所有的东西。这是我的代码:

ma​​in.py

from kivymd.app import MDApp
from kivy.lang import Builder
from kivymd.uix.menu import  MDDropdownMenu, MDMenuItem
from kivy.clock import Clock
from kivy.uix.video import Video
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager
from kivymd.uix.snackbar import Snackbar
from kivymd.uix.screen import MDScreen
from kivymd.uix.textfield import MDTextFieldRound, MDTextField, MDTextFieldRect
from kivy.uix.boxlayout import BoxLayout
from kivymd.uix.dialog import MDDialog
from kivymd.uix.button import MDFlatButton, MDFloatingActionButtonSpeedDial, MDRoundFlatButton
from kivymd.uix.list import MDList, OneLineIconListItem, ILeftBodyTouch, OneLineListItem, ILeftBody, BaseListItem
from kivy.properties import StringProperty, NumericProperty
from kivymd.theming import ThemableBehavior
from kivy.uix.image import Image
from kivymd.uix.behaviors import RectangularElevationBehavior
from kivymd.uix.selectioncontrol import MDCheckbox
from kivy.uix.floatlayout import FloatLayout
from kivymd.uix.tab import MDTabsBase
from kivymd.uix.bottomnavigation import MDBottomNavigation
from kivymd.uix.label import MDLabel
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.core.audio import SoundLoader
import requests

class MainScreen(MDScreen):
    pass
class SearchScreen(MDScreen):
    pass
class WeatherPage(MDScreen):
    pass
class Settings(MDScreen):
    pass
class Manager(ScreenManager):
    pass

class NavDrawerItems(BoxLayout):
    pass
class SearchToolbar(RectangularElevationBehavior, ThemableBehavior, MDBoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        pass


class WeatherApp(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.theme_cls.primary_palette = "Cyan"
        self.screen = Builder.load_file("weather.kv")
        self.apikey = 'bf527f2c0ece63f0e185788e4ea21be3'
        self.base_url = 'http://api.openweathermap.org/data/2.5'
        self.media = SoundLoader.load('Intentions.mp3')

    def build(self):
        return self.screen

    def test(self):
        print('Hello world!')

    def play(self):
        self.media.play()

    def clear(self):
        self.screen.ids.sec_layout.clear_widgets()

    def gomain(self):
        self.screen.ids.screen_manager.current = "main"
        self.screen.ids.nav_drawer.set_state('close')
    
    def search(self):
        self.screen.ids.screen_manager.current = "search"
        self.screen.ids.nav_drawer.set_state('close')
        self.screen.ids.main_search.text = ""

    def settings(self):
        self.screen.ids.screen_manager.current = "settings"
        self.screen.ids.nav_drawer.set_state('close')

    def changetheme(self):
        if self.theme_cls.theme_style == "Light":
            self.theme_cls.theme_style = "Dark"
            self.screen.ids.weather_icon.icon = "white-balance-sunny"
        elif self.theme_cls.theme_style == "Dark":
            self.theme_cls.theme_style = "Light"
            self.screen.ids.weather_icon.icon = "weather-night"

    def find(self):
        try:
            city = self.screen.ids.main_search.text
            full_url = f'self.base_url/weather?q=city&appid=self.apikey'
            weatherinfo = requests.get(full_url)
            result = weatherinfo.json()
            main = result.get('weather')[0].get('main')
            temp = result.get('main').get('temp')
            description = result.get('weather')[0].get('description')
            country = result.get('sys').get('country')
            cityname = result.get('name')
            real_temp = float(temp) - 273.15
            result = round(real_temp)
            self.screen.ids.main_weather.text = description
            self.screen.ids.temperature.text = f'result°'
            if main == "Clear":
                self.screen.ids.main_icon.icon = "weather-cloudy"
            elif main == "Sunny":
                self.screen.ids.main_icon.icon = "weather-sunny"
            elif main == "Clouds":
                self.screen.ids.main_icon.icon = "weather-cloudy"
            elif main == "Rainy":
                self.screen.ids.main_icon.icon = "weather-rainy"

        except Exception as e:
            self.clear()
            self.screen.ids.sec_layout.add_widget(Image(
                source = 'error_connection.png', 
                size = ["200dp", "200dp"],
                pos_hint = "center_x": .5, "center_y": .65
            ))
            self.screen.ids.sec_layout.add_widget(MDLabel(
                text = "Oops!",
                bold = True,
                font_size = 26,
                pos_hint = "center_x": .5, "center_y": .41,
                halign = "center"
            ))

WeatherApp().run()

ma​​in.kv

Manager:
        id: screen_manager
        MainScreen:
            name: "main"
            md_bg_color: 1, 1, 1, 1
            MDToolbar:
                id: toolbar
                md_bg_color: 1, 1, 1, 1
                pos_hint: "top": 1
                specific_text_color: 0, 0, 0, 1
                elevation: 0
                left_action_items: [["sort-variant", lambda x: nav_drawer.set_state("open")]]

            FloatLayout:
                id: sec_layout
                padding: 8
                MDLabel:
                    text: f"main_search.text, Today"
                    pos_hint: "center_x": .55, "center_y": .85
                    font_size: 22
                    halign: "center"
                    bold: True
                BoxLayout:
                    orientation: "horizontal"
                    spacing: 40
                    pos_hint: "center_x": .5, "center_y": .82
                    padding: 60
                    MDCard:
                        orientation: "vertical"
                        size_hint: .6, .4
                        md_bg_color: app.theme_cls.primary_color
                        border_radius: 18
                        radius: [20]
                        MDLabel:
                            id: main_weather
                            text: "Hello"
                            halign: "center"
                            theme_text_color: "Custom"
                            pos_hint: "center_x": .65
                            text_color: 1, 1, 1, 1
                            font_size: 28
                            bold: True
                        MDLabel:
                            id: temperature
                            text: ""
                            halign: "center"
                            theme_text_color: "Custom"
                            pos_hint: "center_x": .65, "center_y": .3
                            text_color: 1, 1, 1, 1
                            font_size: 55
                            bold: True
                        MDIcon:
                            id: main_icon
                            icon: "blank"
                            font_size: 180
                            pos_hint: "center_x": .6
                            theme_text_color: "Custom"
                            text_color: 1, 1, 1, 1
                        Widget:
                            height: "15dp"
                MDLabel:
                    text: "Favorite cities"
                    bold: True
                    pos_hint: "center_x": .55,"center_y": .33
                    font_size: 25

如何使 MainScreen 中的 FloatLayout 可滚动?稍后我会在页面中添加更多内容,并且应用程序中还会有其他屏幕......所以我需要找到一种让它可滚动的方法。我已经尝试过,但要么给出错误,要么出现其他问题......有人对我如何解决这个问题有想法吗?

【问题讨论】:

【参考方案1】:

您可以将FloatLayout 放在ScrollView 中,如下所示:

    ScrollView:
        do_scroll_x: False
        FloatLayout:
            id: sec_layout
            padding: 8
            size_hint_y: None  # this is required for scrolling

【讨论】:

以上是关于如何使浮动布局在 kivymd 中具有滚动视图?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 UICollectionView 的一部分中的所有项目浮动在滚动视图上?

使用自动布局在 UIScrollView 中使用浮动视图滚动犹豫

如何使这种自​​动布局安排与滚动视图一起使用

表格布局可以同时具有水平和垂直滚动视图吗

仅在自动布局中具有固定宽度的垂直滚动视图

如何在 kivymd 的单个屏幕中添加多个布局