Kivy:弹出窗口只能有一个小部件作为内容

Posted

技术标签:

【中文标题】Kivy:弹出窗口只能有一个小部件作为内容【英文标题】:Kivy: Popup can have only one widget as content 【发布时间】:2018-07-19 13:41:44 【问题描述】:

我在 .kv 文件中使用弹出窗口时遇到问题。我知道弹出窗口的内容只能包含一个小部件,但是如果我仅将 GridLayout 作为包含标签和按钮的子项传递,这不应该吗?

这是我的 Python 代码:

import kivy, LabelB
from kivy.app import App
from kivy.graphics import Color, Rectangle
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.properties import ObjectProperty, StringProperty
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition

Builder.load_file('main.kv')

class CustomPopup(Popup):
    pass

class MenuScreen(Screen):

    def open_popup(self):
        the_popup = CustomPopup()
        the_popup.open()

class SurveyScreen(Screen):
    pass

sm = ScreenManager(transition=FadeTransition())
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SurveyScreen(name='survey'))

class MainApp(App):

    def build(self):
        return sm

if __name__ == '__main__':
    MainApp().run()

这是我的 .kv 文件:

<CustomPopup>:
    title: 'Terms of Service'
    size_hint: .5, .5
    auto_dismiss: False
    GridLayout:
        cols: 1
        Label:
            size_hint: .9, .9
            halign: 'center'
            valign: 'middle'
            text: 'Insert terms of service text here'
            text_size: self.width, None
        Button:
            text: 'Close'
            on_release: root.dismiss()

<MenuScreen>:

    FloatLayout:

        canvas.before:
            Rectangle:
                source: 'menu.png'
                size: self.size
                pos: self.pos

        Label:
            pos_hint: 'x': .7, 'y': .85
            text_size: self.size
            font_name: 'Arial'
            font_size: 26
            text: 'Sample'
            bold: True

        Button:
            text: 'Take Survey'
            size_hint: .2, .1
            pos_hint: 'x': .15, 'y': .1
            on_release:
                root.manager.transition.duration = 0.5
                root.manager.current = 'survey'

        Button:
            text: 'Terms of Service'
            size_hint: .2, .1
            pos_hint: 'x': .6-self.size_hint_x, 'y': .1
            on_release: root.open_popup()

        Button:
            text: 'Quit'
            size_hint: .2, .1
            pos_hint: 'x': .85-self.size_hint_x, 'y': .1
            on_release: app.stop()

<SurveyScreen>:

    GridLayout:
        cols: 1
        padding: 20
        spacing: 10

        Label:
            text: 'WELCOME!'
            font_size: 20

        Label:
            text: 'Some boring text'

错误如下:'Popup can only have one widget as content'

我在这里遗漏了一些明显的东西吗?提前致谢。

【问题讨论】:

【参考方案1】:

是的,它应该像你说的那样工作,你的代码是正确的。

问题是 .kv 文件的加载是重复的。由于您的App 子类称为MainApp,如果main.kv 在同一目录中,则会自动加载它(文档:How to load kv)。另一方面,您使用Builder.load_file ('main.kv') 显式上传文件。

您必须删除对Builder 的调用或重命名MainApp/main.kv

如果您删除对 Builder.load_file 的调用,则必须在加载 .kv 后创建 ScreenManager 实例。您可以执行以下操作:

class MainApp (App):

     def build (self):
         sm = ScreenManager (transition = FadeTransition ())
         sm.add_widget (MenuScreen (name = 'menu'))
         sm.add_widget (SurveyScreen (name = 'survey'))
         return sm

【讨论】:

我将应用程序类的名称更改为 SampleApp 并保持 Builder.load_file('main.kv') 行不变,现在一切正常,谢谢!

以上是关于Kivy:弹出窗口只能有一个小部件作为内容的主要内容,如果未能解决你的问题,请参考以下文章

kivy - 绑定弹出窗口关闭以从另一个小部件实例中运行

Kivy - 检查当前是不是显示弹出窗口(因为 Kivy 弹出窗口不是真正的模态(后退按钮/键盘))

在 Kivy 中,如何使用另一个类的关闭按钮关闭弹出窗口?

Kivy 如何创建一个可根据内容调整大小的弹出窗口?

Qt中的弹出窗口

Kivy:弹出窗口中的多个项目不起作用