[英]Popup can have only one widget as content
我在 kivy 接口上工作。 我尝试实现一个弹出窗口,但是当我按下应该触发弹出窗口的按钮时,我收到错误kivy.uix.popup.PopupException: Popup can have only one widget as content
(下面的完整控制台日志)。
我准备的最小可重现示例由 3 个文件组成; main.py 、 my.kv和mygrid.py 。
如何在不改变模块架构的情况下实现按下按钮触发弹出窗口?
包含<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
包含有关<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()
方法中进行导入,而只调用正在运行的App
的show_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.