如何检测ModalView中的按钮是否被按下?

问题描述 投票:0回答:1

我在使用 ModalView 时遇到了问题,该视图在下拉菜单中按下其中一个按钮后打开。

我需要找到一种方法来检测 Kivy 文件中 MyPopup 类中 id“yes”的按钮是否被按下,因为我需要它来触发屏幕类中的函数。为了这个问题,我只是将其命名为

function_to_trigger()

我没有包含该屏幕类中的完整代码,因为首先,它太长了(我的问题足够长,我没有想到),其次,我遇到的唯一问题是这个 MyPopup 类那在我的 Kivy 文件中。

实际结果:

  • 下拉菜单将按预期打开
  • 单击“返回主菜单”按钮后,下拉菜单消失,就像预期的那样
  • 单击“返回主菜单”按钮后出现的 MyPopup ModalView 可以正常工作
  • 如预期
  • MyPopup ModalView 中的“是”按钮将用户重定向到 main_menu 屏幕(我没有在此处包含)
  • 如预期
  • 当用户重定向到 main_menu 屏幕时,MyPopup ModalView 消失
  • 如预期
  • 当按下 ModalView 中的“YES”按钮时,
  • function_to_trigger()
  • NOT
    会被触发。 它没有按预期工作。
预期结果:

仅当按下 ModalView 中的“YES”按钮或用户重定向到 main_menu 屏幕时,才会触发

    function_to_trigger()
  • 
    
  • .py 文件:

from kivy.uix.screenmanager import Screen from kivymd.uix.menu.menu import MDDropdownMenu from kivy.factory import Factory from kivy.uix.modalview import ModalView from kivymd.uix.behaviors.hover_behavior import HoverBehavior from kivy.uix.button import Button from kivy.properties import ListProperty class SomeScreen(Screen): def function_to_trigger(self): print('I was triggered by yes button in the ModalView!') def dropdown(self): menu_list = [ { "viewclass": "OneLineListItem", "text" : "SOUND ON", "theme_text_color": "Custom", "on_release": lambda x="SOUND ON": self.sound_off(menu_list[1]["text"]), "text_color": [1, 1, 1, 1], "text_style": "BUTTON", "font_style": "H6" }, { "viewclass": "OneLineListItem", "text": "RETURN TO MAIN MENU", "on_release": lambda x="RETURN TO MAIN MENU": [Factory.get('MyPopup')().open(), menu.dismiss()], "theme_text_color": "Custom", "text_color": [1, 1, 1, 1], "text_style": "BUTTON", "font_style": "H6" } ] menu = MDDropdownMenu( caller=self.ids.burger_menu, items=menu_list, width_mult=4.2, background_color=[0,0,0,1], radius=10 ) menu.open() ## By the way the function below doesn't work and I also need to find a way how to fix this, but this is a topic for another question I think. def sound_off(self, text_item): if text_item == "SOUND ON": text_item = "SOUND OFF" return text_item else: text_item = "SOUND ON" return text_item class HamburgerButton(Button): pass class ExitButton(Button, HoverBehavior): background = ListProperty((120/255, 120/255, 120/255, 1)) color = ListProperty((1, 1, 1, 1)) def on_enter(self): self.background = (1, 222/255, 89/255, 1) self.color = (0, 0, 0, 1) def on_leave(self): self.background = (120/255, 120/255, 120/255, 1) self.color = (1, 1, 1, 1)

.kv 文件:

<SomeScreen> name: "some_screen" FloatLayout: orientation: 'horizontal' size: 1280, 720 HamburgerButton: id: burger_menu on_release: root.dropdown() <HamburgerButton> size : 95, 95 size_hint: None, None pos_hint: {'center_x': .205, 'center_y': .19} background_normal: 'burger_menu.png' <ExitButton> background_color: 0, 0, 0, 0 background_normal: '' font_name: 'Roboto' font_size: 18 bold: True canvas.before: Color: rgba: self.background RoundedRectangle: size: self.size pos: self.pos radius: [20] <MyPopup@ModalView> size_hint: None, None background_color: 0, 0, 0, 1 size: 450, 250 auto_dismiss: False canvas.before: Color: rgba: root.background_color RoundedRectangle: pos: self.pos size: self.size radius: [20,] BoxLayout: orientation: "vertical" Label: text: "ARE YOU SURE YOU WANT TO EXIT?" font_name: 'Roboto' font_size: 20 bold: True BoxLayout: size_hint_y: 0.3 ExitButton: id: yes text: "YES" on_release: app.root.current = "main_menu" root.dismiss() ExitButton: text: "NO" bold: True on_release: root.dismiss()

汉堡菜单图标:

我尝试解决此问题的方法:

1。使用 SomeScreen 在文件中创建 MyPopup 类,并在 Kivy 文件中“yes”按钮的 on_release 参数下引用它。没成功。

.py 文件:

from kivy.uix.screenmanager import Screen from kivymd.uix.menu.menu import MDDropdownMenu from kivy.factory import Factory from kivy.uix.modalview import ModalView from kivymd.uix.behaviors.hover_behavior import HoverBehavior from kivy.uix.button import Button from kivy.properties import ListProperty class SomeScreen(Screen): def function_to_trigger(self): print('I was triggered by yes button in the ModalView!') def dropdown(self): menu_list = [ { "viewclass": "OneLineListItem", "text" : "SOUND ON", "theme_text_color": "Custom", "on_release": lambda x="SOUND ON": self.sound_off(menu_list[1]["text"]), "text_color": [1, 1, 1, 1], "text_style": "BUTTON", "font_style": "H6" }, { "viewclass": "OneLineListItem", "text": "RETURN TO MAIN MENU", "on_release": lambda x="RETURN TO MAIN MENU": [Factory.get('MyPopup')().open(), menu.dismiss()], "theme_text_color": "Custom", "text_color": [1, 1, 1, 1], "text_style": "BUTTON", "font_style": "H6" } ] menu = MDDropdownMenu( caller=self.ids.burger_menu, items=menu_list, width_mult=4.2, background_color=[0,0,0,1], radius=10 ) menu.open() # By the way the function below doesn't work and I also need to find a way how to fix this, but this is a topic for another question I think. def sound_off(self, text_item): if text_item == "SOUND ON": text_item = "SOUND OFF" return text_item else: text_item = "SOUND ON" return text_item class HamburgerButton(Button): pass class ExitButton(Button, HoverBehavior): background = ListProperty((120/255, 120/255, 120/255, 1)) color = ListProperty((1, 1, 1, 1)) def on_enter(self): self.background = (1, 222/255, 89/255, 1) self.color = (0, 0, 0, 1) def on_leave(self): self.background = (120/255, 120/255, 120/255, 1) self.color = (1, 1, 1, 1) class MyPopup(ModalView): def trigger_function(self): screen = SomeScreen() screen.function_to_trigger() # I also tried the following but it didn't work either. def trigger_function(self): if self.ids.yes.on_release is True: SomeScreen.function_to_trigger(SomeScreen())

.kv 文件:

<MyPopup@ModalView> size_hint: None, None background_color: 0, 0, 0, 1 size: 450, 250 auto_dismiss: False canvas.before: Color: rgba: root.background_color RoundedRectangle: pos: self.pos size: self.size radius: [20,] BoxLayout: orientation: "vertical" Label: text: "ARE YOU SURE YOU WANT TO EXIT?" font_name: 'Roboto' font_size: 20 bold: True BoxLayout: size_hint_y: 0.3 ExitButton: id: yes text: "YES" on_release: app.root.current = "main_menu" root.trigger_function() root.dismiss() ExitButton: text: "NO" bold: True on_release: root.dismiss()

2。在下拉函数中的 Kivy Factory 的帮助下引用 MyPopup 类。它没有按预期工作,因为该函数在打开下拉菜单后立即触发,而该函数应该仅在按下“是”按钮并且用户被重定向到主菜单屏幕时触发。它甚至没有考虑到 ModalView 根本没有打开的事实。

.py 文件:

from kivy.uix.screenmanager import Screen from kivymd.uix.menu.menu import MDDropdownMenu from kivy.factory import Factory from kivy.uix.modalview import ModalView from kivymd.uix.behaviors.hover_behavior import HoverBehavior from kivy.uix.button import Button from kivy.properties import ListProperty class SomeScreen(Screen): def function_to_trigger(self): print('I was triggered by yes button in the ModalView!') def dropdown(self): menu_list = [ { "viewclass": "OneLineListItem", "text" : "SOUND ON", "theme_text_color": "Custom", "on_release": lambda x="SOUND ON": self.sound_off(menu_list[1]["text"]), "text_color": [1, 1, 1, 1], "text_style": "BUTTON", "font_style": "H6" }, { "viewclass": "OneLineListItem", "text": "RETURN TO MAIN MENU", "on_release": lambda x="RETURN TO MAIN MENU": [Factory.get('MyPopup')().open(), menu.dismiss()], "theme_text_color": "Custom", "text_color": [1, 1, 1, 1], "text_style": "BUTTON", "font_style": "H6" } ] menu = MDDropdownMenu( caller=self.ids.burger_menu, items=menu_list, width_mult=4.2, background_color=[0,0,0,1], radius=10 ) menu.open() if Factory.get('MyPopup')().ids.yes.on_release is True: self.function_to_trigger() # By the way the function below doesn't work and I also need to find a way how to fix this, but this is a topic for another question I think. def sound_off(self, text_item): if text_item == "SOUND ON": text_item = "SOUND OFF" return text_item else: text_item = "SOUND ON" return text_item class HamburgerButton(Button): pass class ExitButton(Button, HoverBehavior): background = ListProperty((120/255, 120/255, 120/255, 1)) color = ListProperty((1, 1, 1, 1)) def on_enter(self): self.background = (1, 222/255, 89/255, 1) self.color = (0, 0, 0, 1) def on_leave(self): self.background = (120/255, 120/255, 120/255, 1) self.color = (1, 1, 1, 1)

3.在 SomeScreen 类中创建一个函数,如果 App.get_running_app().root_current = 'main_menu' 则会触发该函数,但它不起作用,我知道它不起作用,因为如果用户已经被重定向到 main_menu 屏幕,那么 SomeScreen 类就不会意识到这一点。反正没成功。

4。在 ScreenManager 中创建一个类似于第 3 点中的函数。基本上,我尝试做的是创建一个函数,如果 App.get_running_app().root.current == 'main_screen' 但会触发 function_to_trigger() ,但是没成功。

5。创建一个类似于第 1 点中的函数,但在 SomeScreen 类中。也没成功。

py.文件

from kivy.uix.screenmanager import Screen from kivymd.uix.menu.menu import MDDropdownMenu from kivy.factory import Factory from kivy.uix.modalview import ModalView from kivymd.uix.behaviors.hover_behavior import HoverBehavior from kivy.uix.button import Button from kivy.properties import ListProperty class SomeScreen(Screen): def function_to_trigger(self): print('I was triggered by yes button in the ModalView!') def trigger_function(self): if Factory.get('MyPopup')().ids.yes.on_release is True: self.function_to_trigger() def dropdown(self): menu_list = [ { "viewclass": "OneLineListItem", "text" : "SOUND ON", "theme_text_color": "Custom", "on_release": lambda x="SOUND ON": self.sound_off(menu_list[1]["text"]), "text_color": [1, 1, 1, 1], "text_style": "BUTTON", "font_style": "H6" }, { "viewclass": "OneLineListItem", "text": "RETURN TO MAIN MENU", "on_release": lambda x="RETURN TO MAIN MENU": [Factory.get('MyPopup')().open(), menu.dismiss()], "theme_text_color": "Custom", "text_color": [1, 1, 1, 1], "text_style": "BUTTON", "font_style": "H6" } ] menu = MDDropdownMenu( caller=self.ids.burger_menu, items=menu_list, width_mult=4.2, background_color=[0,0,0,1], radius=10 ) menu.open() if Factory.get('MyPopup')().ids.yes.on_release is True: self.function_to_trigger() # By the way the function below doesn't work and I also need to find a way how to fix this, but this is a topic for another question I think. def sound_off(self, text_item): if text_item == "SOUND ON": text_item = "SOUND OFF" return text_item else: text_item = "SOUND ON" return text_item class HamburgerButton(Button): pass class ExitButton(Button, HoverBehavior): background = ListProperty((120/255, 120/255, 120/255, 1)) color = ListProperty((1, 1, 1, 1)) def on_enter(self): self.background = (1, 222/255, 89/255, 1) self.color = (0, 0, 0, 1) def on_leave(self): self.background = (120/255, 120/255, 120/255, 1) self.color = (1, 1, 1, 1)

编辑

最小可重复示例:

主.py

from kivymd.app import MDApp from kivy.lang.builder import Builder from windowmanager import WindowManager class MinimalApp(MDApp): def build(self): Builder.load_file('minimalapp.kv') if __name__ == '__main__': MinimalApp().run()

窗口管理器.py

from kivy.uix.screenmanager import ScreenManager from main_menu import MainMenu from second_screen import SecondScreen class WindowManager(ScreenManager): pass

main_menu.py

from kivy.uix.screenmanager import Screen from kivymd.uix.behaviors.hover_behavior import HoverBehavior from kivy.uix.button import Button from kivy.properties import ListProperty class MainMenu(Screen): pass class ButtonMenu(Button, HoverBehavior): background = ListProperty((0, 0, 0, 1)) color = ListProperty((1, 1, 1, 1)) def on_enter(self): self.background = (1, 222/255, 89/255, 1) self.color = (0, 0, 0, 1) def on_leave(self): self.background = (0, 0, 0, 1) self.color = (1, 1, 1, 1)

main_menu.kv

<MainMenu>: name: 'main_menu' FloatLayout: orientation: 'horizontal' size: 1280, 720 ButtonMenu: text: 'GO TO SOME SCREEN' pos_hint: {'center_x': .5, 'center_y': .42} on_release: app.root.current = "second_screen" root.manager.transition.direction = "left" <ButtonMenu> background_color: 0, 0, 0, 0 background_normal: '' size_hint: 0.5, 0.11 font_size: 32 font_name: 'Roboto' bold: True canvas.before: Color: rgba: self.background RoundedRectangle: size: self.size pos: self.pos radius: [28] Color: rgba: (0, 0, 0, 1) # separate color for line border Line: rounded_rectangle: (self.pos[0], self.pos[1], self.size[0], self.size[1], 28) width: 2

最小应用程序.kv

#: include main_menu.kv #: include second_screen.kv WindowManager: MainMenu: SecondScreen:

第二屏幕.py

from kivy.uix.screenmanager import Screen from kivymd.uix.menu.menu import MDDropdownMenu from kivy.factory import Factory from kivy.uix.modalview import ModalView from kivymd.uix.behaviors.hover_behavior import HoverBehavior from kivy.uix.button import Button from kivy.properties import ListProperty class SecondScreen(Screen): def function_to_trigger(self): print('I was triggered by yes button in the ModalView!') def dropdown(self): menu_list = [ { "viewclass": "OneLineListItem", "text": "SOUND ON", "theme_text_color": "Custom", "on_release": lambda x="SOUND ON": self.sound_off(menu_list[1]["text"]), "text_color": [1, 1, 1, 1], "text_style": "BUTTON", "font_style": "H6" }, { "viewclass": "OneLineListItem", "text": "RETURN TO MAIN MENU", "on_release": lambda x="RETURN TO MAIN MENU": [Factory.get('MyPopup')().open(), menu.dismiss()], "theme_text_color": "Custom", "text_color": [1, 1, 1, 1], "text_style": "BUTTON", "font_style": "H6" } ] menu = MDDropdownMenu( caller=self.ids.burger_menu, items=menu_list, width_mult=4.2, background_color=[0, 0, 0, 1], radius=10 ) menu.open() ## By the way the function below doesn't work and I also need to find a way how to fix this, but this is a topic for another question I think. def sound_off(self, text_item): if text_item == "SOUND ON": text_item = "SOUND OFF" return text_item else: text_item = "SOUND ON" return text_item class HamburgerButton(Button): pass class ExitButton(Button, HoverBehavior): background = ListProperty((120/255, 120/255, 120/255, 1)) color = ListProperty((1, 1, 1, 1)) def on_enter(self): self.background = (1, 222/255, 89/255, 1) self.color = (0, 0, 0, 1) def on_leave(self): self.background = (120/255, 120/255, 120/255, 1) self.color = (1, 1, 1, 1)

第二屏幕.kv

<SecondScreen> name: 'second_screen' FloatLayout: orientation: 'horizontal' size: 1280, 720 HamburgerButton: id: burger_menu on_release: root.dropdown() <HamburgerButton> size : 95, 95 size_hint: None, None pos_hint: {'center_x': .205, 'center_y': .19} background_normal: 'burger_menu.png' <ExitButton> background_color: 0, 0, 0, 0 background_normal: '' font_name: 'Roboto' font_size: 18 bold: True canvas.before: Color: rgba: self.background RoundedRectangle: size: self.size pos: self.pos radius: [20] <MyPopup@ModalView> size_hint: None, None background_color: 0, 0, 0, 1 size: 450, 250 auto_dismiss: False canvas.before: Color: rgba: root.background_color RoundedRectangle: pos: self.pos size: self.size radius: [20,] BoxLayout: orientation: "vertical" Label: text: "ARE YOU SURE YOU WANT TO EXIT?" font_name: 'Roboto' font_size: 20 bold: True BoxLayout: size_hint_y: 0.3 ExitButton: id: yes text: "YES" on_release: app.root.current = "main_menu" root.dismiss() ExitButton: text: "NO" bold: True on_release: root.dismiss()


python kivy kivy-language kivymd
1个回答
0
投票

app.root.get_screen('second_screen').function_to_trigger()

on_release:

按钮的

YES
    

© www.soinside.com 2019 - 2024. All rights reserved.