Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kivy(Python)中部分可见的下拉列表_Python_User Interface_Drop Down Menu_Kivy - Fatal编程技术网

Kivy(Python)中部分可见的下拉列表

Kivy(Python)中部分可见的下拉列表,python,user-interface,drop-down-menu,kivy,Python,User Interface,Drop Down Menu,Kivy,我试图在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 f

我试图在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: ""
#:kivy 1.0.9
:
背景颜色:self.background\u color\u down如果self.state==“down”否则self.background\u color\u normal
颜色:(1,1,1,1)
在以下情况之前:
颜色:
rgba:self.background\u颜色
矩形:
pos:self.pos
大小:self.size
在下列情况之后:
颜色:
rgba:self.separator\u颜色
行:
矩形:self.x、self.y、self.width、self.height
:
尺寸提示:无
身高:40
在以下情况之前:
颜色:
rgba:self.background\u颜色
矩形:
pos:self.pos
大小:self.size
在下列情况之后:
颜色:
rgba:self.separator\u颜色
行:
点:self.x,self.y,self.x+self.width,self.y
盒子布局:
方向:“垂直”
菜单栏:
菜单菜单:
文本:“子菜单1”
菜单下拉列表:
按钮:
文本:“按钮11”
发布时:应用程序按钮(11)
按钮:
文本:“按钮12”
发布时:应用程序按钮(12)
按钮:
文本:“按钮13”
发布时:应用程序按钮(13)
菜单按钮:
文本:“按钮2”
发布时:应用程序按钮(2)
菜单按钮:
文本:“按钮3”
发布时:应用程序按钮(3)
按钮:
文本:“没有”
背景颜色:0.4,0.4,0.4,1
背景_正常:“

如果您知道发生了什么,或者您可以将我重定向到更合适的地方以找到答案,那就太好了。

正如@恶劣天气警告的那样,我没有正确使用下拉菜单。您不应该在kv文件中直接添加下拉小部件

因此,我查看了kivy(解释和源代码)中的
操作栏是如何工作的,并因此更新了我的菜单栏

下面是我的python代码:

#!/usr/bin/env python3

from kivy.app import App
from kivy.lang import Builder
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.uix.spinner import Spinner
from kivy.properties import ListProperty, ObjectProperty,\
        StringProperty, BooleanProperty, NumericProperty
#from kivy.uix.actionbar import ActionBar, ActionView, ActionGroup, ActionButton

class MenuItem(Widget):
    '''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])
    text_color = ListProperty([1,1,1,1])
    inside_group = BooleanProperty(False)
    pass

class MenuSubmenu(MenuItem, Spinner):
    triangle = ListProperty()

    def __init__(self, **kwargs):
        self.list_menu_item = []
        super().__init__(**kwargs)
        self.dropdown_cls = MenuDropDown

    def add_widget(self, item):
        self.list_menu_item.append(item)
        self.show_submenu()

    def show_submenu(self):
        self.clear_widgets()
        for item in self.list_menu_item:
            item.inside_group = True
            self._dropdown.add_widget(item)

    def _build_dropdown(self, *largs):
        if self._dropdown:
            self._dropdown.unbind(on_dismiss=self._toggle_dropdown)
            self._dropdown.dismiss()
            self._dropdown = None
        self._dropdown = self.dropdown_cls()
        self._dropdown.bind(on_dismiss=self._toggle_dropdown)

    def _update_dropdown(self, *largs):
        pass

    def _toggle_dropdown(self, *largs):
        self.is_open = not self.is_open
        ddn = self._dropdown
        ddn.size_hint_x = None
        if not ddn.container:
            return
        children = ddn.container.children
        if children:
            ddn.width = max(self.width, max(c.width for c in children))
        else:
            ddn.width = self.width
        for item in children:
            item.size_hint_y = None
            item.height = max([self.height, 48])

    def clear_widgets(self):
        self._dropdown.clear_widgets()

class MenuDropDown(DropDown):
        pass

class MenuButton(MenuItem,Button):
    icon = StringProperty(None, allownone=True)
    pass

class MenuEmptySpace(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)

if __name__ == '__main__':

    class MenuApp(App):
        def button(self, nb):
            print("Button", nb, "triggered")

    MenuApp().run()
下面是相应的文件
menu.kv

#:kivy 1.0.9

<MenuButton>:
    size_hint_x: None if not root.inside_group else 1
    width: self.texture_size[0] + 32
    Image:
        allow_stretch: True
        opacity: 1 if root.icon else 0
        source: root.icon
        pos: root.x + 4, root.y + 4
        size: root.width - 8, root.height - 8

<MenuSubmenu>:
    size_hint_x: None
    width: self.texture_size[0] + 32
    triangle: (self.right-14, self.y+7, self.right-7, self.y+7, self.right-7, self.y+14)
    canvas.after:
        Color:
            rgba: self.separator_color
        Triangle:
            points: self.triangle

<MenuButton,MenuSubmenu>:
    background_normal: ""
    background_down: ""
    background_color: self.background_color_down if self.state=='down' else self.background_color_normal
    color: self.text_color

<MenuEmptySpace>:
    size_hint_x: 1

<MenuItem>:
    background_color: self.background_color_normal
    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: 48
    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

BoxLayout:
    orientation: "vertical"

    MenuBar:
        MenuButton:
            icon: "/home/matthieu/internships/singapore/drawings/joytube_color_small.png"
            width: 100
        MenuButton:
            text: "Button 1"
            on_release: app.button(1)
        MenuSubmenu:
            text: "Submenu 2"
            MenuButton:
                text: "Button 21"
                on_release: app.button(21)
            MenuButton:
                text: "Button 22"
                on_release: app.button(22)
            MenuButton:
                text: "Button 23"
                on_release: app.button(23)
        MenuEmptySpace:
        MenuSubmenu:
            text: "Submenu 3"
            MenuButton:
                text: "Button 31"
                on_release: app.button(31)

    Button:
        text: "Nothing"
        background_color: 0.4, 0.4, 0.4, 1
        background_normal: ""

    MenuBar:
        height: 30
#:kivy 1.0.9
:
大小\u提示\u x:如果不是root,则无。组内\u其他1
宽度:自纹理大小[0]+32
图片:
允许拉伸:真
不透明度:如果root.icon为0,则为1
来源:root.icon
位置:根x+4,根y+4
尺寸:根.宽-8,根.高-8
:
大小提示:无
宽度:自纹理大小[0]+32
三角形:(self.right-14,self.y+7,self.right-7,self.y+7,self.right-7,self.y+14)
在下列情况之后:
颜色:
rgba:self.separator\u颜色
三角形:
点:自三角
:
背景_正常:“
背景“向下”:
背景颜色:self.background\u color\u down如果self.state==“down”否则self.background\u color\u normal
颜色:self.text\u颜色
:
大小提示:1
:
背景颜色:self.background\u color\u normal
在以下情况之前:
颜色:
rgba:self.background\u颜色
矩形:
pos:self.pos
大小:self.size
在下列情况之后:
颜色:
rgba:self.separator\u颜色
行:
矩形:self.x、self.y、self.width、self.height
:
尺寸提示:无
身高:48
在以下情况之前:
颜色:
rgba:self.background\u颜色
矩形:
pos:self.pos
大小:self.size
在下列情况之后:
颜色:
rgba:self.separator\u颜色
行:
矩形:self.x、self.y、self.width、self.height
盒子布局:
方向:“垂直”
菜单栏:
菜单按钮:
图标:“/home/matthieu/internications/singapore/drawings/joydube\u color\u small.png”
宽度:100
菜单按钮:
文本:“按钮1”
发布时:应用程序按钮(1)
菜单菜单:
文本:“子菜单2”
菜单按钮:
文本:“按钮21”
发布时:应用程序按钮(21)
菜单按钮:
文本:“按钮22”
发布时:应用程序按钮(22)
菜单按钮:
文本:“按钮23”
发布时:应用程序按钮(23)
菜单空间:
菜单菜单:
文本:“子菜单3”
菜单按钮:
文本:“按钮31”
发布时:应用程序按钮(31)
按钮:
文本:“没有”
背景颜色:0.4,0.4,0.4,1
背景_正常:“
菜单栏:
身高:30

希望它能帮助其他想要制作菜单栏的人。

你不应该像这样直接向家长添加下拉列表,而应该使用
打开
方法。我不是,这只有在单击子菜单时才可见(您可以看到在类菜单的发布时调用函数
open
)这个问题是因为我没有给下拉菜单的元素一个高度,所以在
打开
函数中调用的
重新定位
解析
函数遇到了问题。在你的kv代码中,你直接在菜单菜单中添加了一个菜单下拉菜单。好吧,我错了,我是kivy的新手,因为尽管我可以这样做。那么是否可以在一个kv文件中定义一个呢?或者它应该被定义为一个类似于示例中的类,而不是handyOk,我想我可能有一个想法,可以基于类
ActionGroup
\u build\u dropdown
,…)中的函数来实现这一点这可以找到感谢@恶劣的警告。