简体   繁体   English

如何在 kivy 图表上显示 kivy 上下文菜单?

[英]How to display a kivy ContextMenu on top of a kivy Graph?

I am still figuring out kivy, so forgive me if this is a silly question.我还在弄清楚 kivy,如果这是一个愚蠢的问题,请原谅我。 Essentially, I have an application that uses a graph to show data to the user.本质上,我有一个使用图表向用户显示数据的应用程序。 In addition, I would like to have an application menu at the top of the window with nested menus.另外,我想在 window 的顶部有一个带有嵌套菜单的应用程序菜单。 This file does almost everything I want:这个文件几乎完成了我想要的一切:

import kivy
from kivy.app import App
from kivy.lang import Builder
import kivy_garden.contextmenu
import kivy_garden.graph

kv = """
BoxLayout:
    orientation: 'vertical'
    id: layout
    AppMenu:
        id: app_menu
        top: root.height
        cancel_handler_widget: layout

        AppMenuTextItem:
            text: "Menu #1"
            ContextMenu:
                ContextMenuTextItem:
                    text: "Item #11"
                ContextMenuTextItem:
                    text: "Item #12"
        AppMenuTextItem:
            text: "Menu Menu Menu #2"
            ContextMenu:
                ContextMenuTextItem:
                    text: "Item #21"
                ContextMenuTextItem:
                    text: "Item #22"
                ContextMenuTextItem:
                    text: "ItemItemItem #23"
                ContextMenuTextItem:
                    text: "Item #24"
                    ContextMenu:
                        ContextMenuTextItem:
                            text: "Item #241"
                        ContextMenuTextItem:
                            text: "Hello, World!"
                            on_release: app.say_hello(self.text)
                        # ...
                ContextMenuTextItem:
                    text: "Item #5"
    Graph:
        border_color: [0, 0, 0, 0]
        #background_color: [0.25, 0.25, 0.25, 1]
"""

class MyApp(App):
    def build(self):
        self.title = 'Simple app menu example'
        return Builder.load_string(kv)

    def say_hello(self, text):
        print(text)
        self.root.ids['app_menu'].close_all()

if __name__ == '__main__':
    MyApp().run()

You'll notice that when the menus appear, the white graph border covers them.您会注意到,当菜单出现时,白色的图形边框会覆盖它们。 If we uncomment the last line in the kivy builder string and give the graph a gray background color, the graph is drawn on top of the application menu and nothing appears when the menu is opened.如果我们取消注释 kivy 构建器字符串中的最后一行并为图形提供灰色背景色,则图形将绘制在应用程序菜单的顶部,打开菜单时不会出现任何内容。

I know that kivy_garden.graph is using Canvas under the hood to draw itself.我知道kivy_garden.graph在引擎盖下使用Canvas来绘制自己。 So, is there a way for widgets to draw on top of another widget's canvas?那么,有没有办法让小部件在另一个小部件的 canvas 之上绘制? I have also tried using spinners and dropdowns to solve this issue, but to no avail.我也尝试使用微调器和下拉菜单来解决此问题,但无济于事。

Thanks for your help!谢谢你的帮助!

I think that is a result of the order in which children of the layout are drawn.我认为这是布局子级绘制顺序的结果。 With the Graph as the last item in the layout, it gets drawn last, over the menu.Graph作为布局中的最后一项,它在菜单上最后绘制。 Here is a modified version of your kv that puts the menu last in the layout:这是您的kv的修改版本,它将菜单放在布局中的最后:

FloatLayout:
    id: layout
    Graph:
        size_hint: 1, None
        height: root.height - app_menu.height
        border_color: [0, 0, 0, 0]
        background_color: [0.25, 0.25, 0.25, 1]
    AppMenu:
        id: app_menu
        top: root.height
        cancel_handler_widget: layout

        AppMenuTextItem:
            text: "Menu #1"
            ContextMenu:
                ContextMenuTextItem:
                    text: "Item #11"
                ContextMenuTextItem:
                    text: "Item #12"
        AppMenuTextItem:
            text: "Menu Menu Menu #2"
            ContextMenu:
                ContextMenuTextItem:
                    text: "Item #21"
                ContextMenuTextItem:
                    text: "Item #22"
                ContextMenuTextItem:
                    text: "ItemItemItem #23"
                ContextMenuTextItem:
                    text: "Item #24"
                    ContextMenu:
                        ContextMenuTextItem:
                            text: "Item #241"
                        ContextMenuTextItem:
                            text: "Hello, World!"
                            on_release: app.say_hello(self.text)
                        # ...
                ContextMenuTextItem:
                    text: "Item #5"

I have used FloatLayout instead of BoxLayout in order to place the AppMenu last in the layout, and that required setting the height of the Graph (the height of the AppMenu is already fixed).我使用FloatLayout而不是BoxLayout来将AppMenu放在布局的最后,这需要设置GraphheightAppMenuheight已经固定)。

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

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