【发布时间】:2015-06-30 04:30:00
【问题描述】:
我正在尝试在 Kivy(Python 的 GUI)中创建一个通用菜单栏,但我遇到了下拉菜单问题。它们只是部分出现,我不知道为什么(参见子菜单 1):
如果你想检查,这是我的代码:
#!/usr/bin/env python3
from kivy.app import App
#from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.dropdown import DropDown
from kivy.properties import ListProperty, ObjectProperty
#from kivy.uix.actionbar import ActionBar, ActionView, ActionGroup, ActionButton
class MenuItem(ButtonBehavior, Label):
'''Background color, in the format (r, g, b, a).'''
background_color_normal = ListProperty([0.2, 0.2, 0.2, 1])
background_color_down = ListProperty([0.3, 0.3, 0.3, 1])
background_color = ListProperty()
separator_color = ListProperty([0.8, 0.8, 0.8, 1])
pass
class MenuSubmenu(MenuItem):
# The list of submenu items in dropdown menu
submenu = ObjectProperty(None)
def add_widget(self, submenu, **kwargs):
if isinstance(submenu, MenuDropDown):
self.submenu = submenu
super().add_widget(submenu, **kwargs)
def on_release(self, **kwargs):
super().on_release(**kwargs)
self.submenu.open(self)
class MenuDropDown(DropDown):
pass
class MenuButton(MenuItem):
pass
class MenuBar(BoxLayout):
'''Background color, in the format (r, g, b, a).'''
background_color = ListProperty([0.2, 0.2, 0.2, 1])
separator_color = ListProperty([0.8, 0.8, 0.8, 1])
def __init__(self, **kwargs):
self.itemsList = []
super().__init__(**kwargs)
def add_widget(self, item, index=0):
if not isinstance(item, MenuItem):
raise TypeError("MenuBar accepts only MenuItem widgets")
super().add_widget(item, index)
if index == 0:
index = len(self.itemsList)
self.itemsList.insert(index, item)
class MenuApp(App):
def button(self, nb):
print("Button", nb, "triggered")
if __name__ == '__main__':
MenuApp().run()
这里是kv文件:
#:kivy 1.0.9
<MenuItem>:
background_color: self.background_color_down if self.state=='down' else self.background_color_normal
color: (1,1,1,1)
canvas.before:
Color:
rgba: self.background_color
Rectangle:
pos: self.pos
size: self.size
canvas.after:
Color:
rgba: self.separator_color
Line:
rectangle: self.x,self.y,self.width,self.height
<MenuBar>:
size_hint_y: None
height: 40
canvas.before:
Color:
rgba: self.background_color
Rectangle:
pos: self.pos
size: self.size
canvas.after:
Color:
rgba: self.separator_color
Line:
points: self.x, self.y, self.x + self.width, self.y
BoxLayout:
orientation: "vertical"
MenuBar:
MenuSubmenu:
text: "Submenu 1"
MenuDropDown:
Button:
text: "Button 11"
on_release: app.button(11)
Button:
text: "Button 12"
on_release: app.button(12)
Button:
text: "Button 13"
on_release: app.button(13)
MenuButton:
text: "Button 2"
on_release: app.button(2)
MenuButton:
text: "Button 3"
on_release: app.button(3)
Button:
text: "Nothing"
background_color: 0.4, 0.4, 0.4, 1
background_normal: ""
如果您知道发生了什么,或者您可以将我重定向到更合适的地方以找到答案,那就太好了。
【问题讨论】:
-
你不应该像这样直接将 DropDown 添加到父级,而应该使用
open方法。 -
我不是,这只有在我点击子菜单时才可见(你可以看到函数
open在MenuSubmenu类的on_release事件上被调用)问题是由于事实上,我没有为下拉列表的元素指定高度,因此在open函数中调用的_reposition或_resomething函数遇到了问题。 -
在您的 kv 代码中,您做 将 MenuDropDown 直接添加到 MenuSubmenu。
-
好吧,我误解了这一点,我是 kivy 的新手,由于this exemple,我认为我可以做到这一点。那么是否可以在 kv 文件中定义一个?还是应该将其定义为示例中的某个不方便的类
-
好的,我想我可能对如何根据类
ActionGroup(_build_dropdown, ...) 中的函数来做这件事有一个想法,这可以找到here 谢谢@严重警告。
标签: python user-interface drop-down-menu kivy