Kivy的ScreenManager和Popups不想一起工作

时间:2016-10-19 19:40:55

标签: python kivy kivy-language

如标题所述 - 我被困住了。我一直在玩代码,只要我将ScreenManager和Popup分开,一切正常。一旦合并 - 他们拒绝合作。无论如何,这是一个简单的应用程序,显示我遇到的问题。

from kivy.lang import Builder
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
from kivy.uix.screenmanager import Screen, ScreenManager

class First(GridLayout,Screen):
    def show_popup(self):
        Popp().open()
    pass

class Second(Screen):
    pass

class Popp(Popup):
    pass

class ScreenManagement(ScreenManager):
    pass

app = Builder.load_file("main.kv")

class MainApp(App):
    def build(self):
        return app


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

和main.kv文件

ScreenManagement:
    First:
    Second:

<First>:
    name:"First"
    rows: 2
    Button:
        text: "FirstButton"
        on_release: app.root.current = "Second"
    Button:
        text: "Show popup"
        on_release: root.show_popup()

<Second>:
    name:"Second"
    Button:
        text: "BUTTON"
        on_release: app.root.current = "First"

<Popp>:
    title: "testing"
    text: "Hello world"
    size_hint: None,None
    size: 400,400
    auto_dismiss: False
    Button:
        text: "Okay"
        on_press: root.dismiss()

应用程序启动,第一个和第二个屏幕正在运行,但在尝试弹出时我最终得到:

kivy.uix.popup.PopupException: Popup can have only one widget as content

不知何故,Screen被视为Popp中的一个小部件?还是我非常误解了kivy docs?

3 个答案:

答案 0 :(得分:1)

这是加载kv文件的错误,在这种情况下应该抛出异常。

你在代码中做的是加载kv文件两次,导致一些奇怪的行为。只需删除Builder.load_file(..)即可。该文件将自动加载。

此外,永远不要对像class First(GridLayout, Screen)这样的小部件进行双重子类化,因为它可能会导致一些问题。而是在屏幕内创建网格布局。

答案 1 :(得分:0)

将Popup中的元素放在布局中,例如:Boxlayout。

这就是我的意思:

<Popp>:
    title: "testing"
    BoxLayout:
        orientation: 'vertical'
        size_hint: None,None
        size: 400,400
        Label:
           text: "Hello world"
        Button:
            text: "Okay"
            on_press: root.dismiss()

答案 2 :(得分:0)

使用kivy Builder.load_file和Popup时遇到同样的问题,他们不能一起工作。 解决方案很简单,在python代码端构建弹出窗口。这是一个加载弹出示例:

蟒:

    from kivy.app import App
    from kivy.uix.popup import Popup
    from kivy.factory import Factory
    from kivy.properties import ObjectProperty
    from kivy.clock import Clock
    from kivy.lang import Builder
    from kivy.uix.popup import Popup
    from kivy.uix.image import Image
    from kivy.uix.label import Label
    from kivy.uix.boxlayout import BoxLayout

    import time, threading


    buildKV = Builder.load_file("example.kv")

    class ExampleApp(App):
        def show_popup(self):
            content = BoxLayout(orientation= "vertical")
            image=Image(source= 'files/loading.gif', anim_delay= 0)
            label=Label(text= 'Model is Running.\nBe Patient Please.')
            content.add_widget(image)
            content.add_widget(label)
            self.popup = Popup(title='Model is Running.',
                      size_hint=(.250, .785),
                      content=content, auto_dismiss=False)

            self.popup.open()

        def process_button_click(self):
            # Open the pop up
            self.show_popup()

            # Call some method that may take a while to run.
            # I'm using a thread to simulate this
            mythread = threading.Thread(target=self.something_that_takes_5_seconds_to_run)
            mythread.start()

        def something_that_takes_5_seconds_to_run(self):
            thistime = time.time()
            while thistime + 10 > time.time(): # 5 seconds
                time.sleep(1)

            # Once the long running task is done, close the pop up.
            self.pop_up.dismiss()

    if __name__ == "__main__":
        ExampleApp().run()

kivy:

   BoxLayout:
        Button:
            height: 40
            width: 100
            size_hint: (None, None)
            text: 'Click Me'
            on_press: app.process_button_click()