繁体   English   中英

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

[英]Popup can have only one widget as content

我在 kivy 接口上工作。 我尝试实现一个弹出窗口,但是当我按下应该触发弹出窗口的按钮时,我收到错误kivy.uix.popup.PopupException: Popup can have only one widget as content (下面的完整控制台日志)。

我准备的最小可重现示例由 3 个文件组成; main.pymy.kvmygrid.py

如何在不改变模块架构的情况下实现按下按钮触发弹出窗口?

我的.kv

包含<GridLayout> (绿色部分)和<ScrollView> (蓝色部分)的结构

<ScrollView>:
    canvas:
        Color:
            rgb: 0, 0, 1
        Rectangle:
            pos: self.pos
            size: self.size

<GridLayout>:
    canvas:
        Color:
            rgb: 0, 1, 0
        Rectangle:
            pos: self.pos
            size: self.size

    cols:1
    size: root.width, root.height

    Button:
        width: root.width
        text: "Submit"
        on_press:root.SendButton()
        size_hint: 1, None

mygrid.py

包含有关<GridLayout>的逻辑。 在示例情况下,它只决定何时触发弹出窗口

from kivy.uix.gridlayout import GridLayout

class MyGrid(GridLayout):
    def SendButton(self):
        from main import myApp
        myApp().show_popup()

主文件

运行应用程序

  • <ScrollView>中嵌套<GridLayout> >

  • 定义弹出窗口

    import kivy from kivy.app import App from mygrid import MyGrid from kivy.uix.scrollview import ScrollView from kivy.core.window import Window from kivy.uix.popup import Popup from kivy.lang import Builder Builder.load_string(''' <CustomPopup>: size_hint: .5, .5 auto_dismiss: False title: 'Hello world' Button: text: 'Click me to dismiss' on_press: root.dismiss() ''') class CustomPopup(Popup): pass class myApp(App): def build(self): layout = MyGrid(cols=1, padding=10, spacing=10, size_hint_y=None) layout.bind(minimum_height=layout.setter('height')) root = ScrollView(size_hint=(1, None), size=(Window.width, Window.height)) root.add_widget(layout) return root def show_popup(self): p = CustomPopup() p.open() if __name__ == "__main__": myApp().run()

完整的控制台日志:

PS C:\Users\EXO\Desktop\mre>  & 'C:\Users\EXO\AppData\Local\Programs\Python\Python310\python.exe' 'c:\Users\EXO\.vscode\extensions\ms-python.python-2022.10.1\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher' '51462' '--' 'c:\Users\EXO\Desktop\mre\main.py'
[INFO   ] [Logger      ] Record log in C:\Users\EXO\.kivy\logs\kivy_22-07-29_14.txt
[INFO   ] [deps        ] Successfully imported "kivy_deps.angle" 0.3.2
[INFO   ] [deps        ] Successfully imported "kivy_deps.glew" 0.3.1 
[INFO   ] [deps        ] Successfully imported "kivy_deps.sdl2" 0.4.5 
[INFO   ] [Kivy        ] v2.1.0
[INFO   ] [Kivy        ] Installed at "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\_
_init__.py"
[INFO   ] [Python      ] v3.10.5 (tags/v3.10.5:f377153, Jun  6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)]
[INFO   ] [Python      ] Interpreter at "C:\Users\EXO\AppData\Local\Programs\Python\Python310\python.exe"
[INFO   ] [Logger      ] Purge log fired. Processing...
[INFO   ] [Logger      ] Purge finished!
[INFO   ] [Factory     ] 189 symbols loaded
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2 (img_pil, img_ffpyplayer ignored)
[INFO   ] [Window      ] Provider: sdl2
[INFO   ] [Window      ] Activate GLES2/ANGLE context
[INFO   ] [GL          ] Using the "OpenGL" graphics system
[INFO   ] [GL          ] Backend used <angle_sdl2>
[INFO   ] [GL          ] OpenGL version <b'OpenGL ES 3.0.0 (ANGLE 2.1.17461 git hash: b790affce32e)'>
[INFO   ] [GL          ] OpenGL vendor <b'Google Inc. (Intel)'>
[INFO   ] [GL          ] OpenGL renderer <b'ANGLE (Intel, Intel(R) HD Graphics 3000 Direct3D11 vs_4_1 ps_4_1, D3D11-
9.17.10.4459)'>
[INFO   ] [GL          ] OpenGL parsed version: 3, 0
[INFO   ] [GL          ] Shading version <b'OpenGL ES GLSL ES 3.00 (ANGLE 2.1.17461 git hash: b790affce32e)'>       
[INFO   ] [GL          ] Texture max size <8192>
[INFO   ] [GL          ] Texture max units <16>
[INFO   ] [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
[INFO   ] [Text        ] Provider: sdl2
[INFO   ] [Base        ] Start application main loop
[INFO   ] [GL          ] NPOT texture support is available
[INFO   ] [Base        ] Leaving application in progress...
 Traceback (most recent call last):
   File "c:\Users\EXO\Desktop\mre\main.py", line 36, in <module>
     myApp().run()
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\app.py", line 955, in run
     runTouchApp()
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\base.py", line 574, in runTouchApp        
     EventLoop.mainloop()
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\base.py", line 339, in mainloop
     self.idle()
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\base.py", line 383, in idle
     self.dispatch_input()
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\base.py", line 334, in dispatch_input     
     post_dispatch_input(*pop(0))
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\base.py", line 263, in post_dispatch_input
     listener.dispatch('on_motion', etype, me)
   File "kivy\_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\core\window\__init__.py", line 1664, in on_motion
     self.dispatch('on_touch_up', me)
   File "kivy\_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\core\window\__init__.py", line 1701, in on_touch_up
     if w.dispatch('on_touch_up', touch):
   File "kivy\_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\scrollview.py", line 968, in on_touch_up
     if self.dispatch('on_scroll_stop', touch):
   File "kivy\_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\scrollview.py", line 1005, in on_scroll_stop
     self.simulate_touch_down(touch)
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\scrollview.py", line 668, in simulate_touch_down
     ret = super(ScrollView, self).on_touch_down(touch)
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\widget.py", line 589, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\widget.py", line 589, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\behaviors\button.py", line 151, in on_touch_down
     self.dispatch('on_press')
   File "kivy\_event.pyx", line 727, in kivy._event.EventDispatcher.dispatch
   File "kivy\_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
   File "kivy\_event.pyx", line 1191, in kivy._event.EventObservers._dispatch
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\lang\builder.py", line 55, in custom_callback
     exec(__kvlang__.co_value, idmap)
   File "c:\Users\EXO\Desktop\mre\my.kv", line 23, in <module>
     on_press:root.SendButton()
   File "c:\Users\EXO\Desktop\mre\mygrid.py", line 6, in SendButton
     myApp().show_popup()
   File "c:\Users\EXO\Desktop\mre\main.py", line 32, in show_popup
     p = CustomPopup()
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\modalview.py", line 195, in __init__  
     super(ModalView, self).__init__(**kwargs)
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\anchorlayout.py", line 68, in __init__
     super(AnchorLayout, self).__init__(**kwargs)
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\layout.py", line 76, in __init__      
     super(Layout, self).__init__(**kwargs)
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\widget.py", line 366, in __init__     
     self.apply_class_lang_rules(
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\widget.py", line 470, in apply_class_lang_rules
     Builder.apply(
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\lang\builder.py", line 540, in apply      
     self._apply_rule(
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\lang\builder.py", line 659, in _apply_rule
     widget.add_widget(child)
   File "C:\Users\EXO\AppData\Local\Programs\Python\Python310\lib\site-packages\kivy\uix\popup.py", line 216, in add_widget    
     raise PopupException(
 kivy.uix.popup.PopupException: Popup can have only one widget as content
PS C:\Users\EXO\Desktop\mre> 

问题是你的代码:

def SendButton(self):
    from main import myApp
    myApp().show_popup()

此处的import会导致main.py中的Builder.load_string()第二次执行(第一次是在您运行App时)。 第二次执行会导致<CustomPopup>规则被加载两次,这导致CustomPopup规则试图将两个Buttons放入Popup中,并触发错误消息。

此外,这是创建 myApp 的另一个实例( myApp myApp()总是创建一个新实例)。 然后调用该新实例的show_popup()方法。 更好的方法是不在SendButton()方法中进行导入,而只调用正在运行的Appshow_popup()方法。 像这样:

from kivy.uix.gridlayout import GridLayout
from kivy.app import App

class MyGrid(GridLayout):
    def SendButton(self):
        App.get_running_app().show_popup()

此代码获取当前正在运行的App并调用其show_popup()方法,而不从main.py导入任何内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM