我在使用 ModalView 时遇到了问题,该视图在下拉菜单中按下其中一个按钮后打开。
我需要找到一种方法来检测 Kivy 文件中 MyPopup 类中 id“yes”的按钮是否被按下,因为我需要它来触发屏幕类中的函数。为了这个问题,我只是将其命名为
function_to_trigger()
我没有包含该屏幕类中的完整代码,因为首先,它太长了(我的问题足够长,我没有想到),其次,我遇到的唯一问题是这个 MyPopup 类那在我的 Kivy 文件中。
实际结果:
function_to_trigger()
NOT会被触发。 它没有按预期工作。
仅当按下 ModalView 中的“YES”按钮或用户重定向到 main_menu 屏幕时,才会触发
function_to_trigger()
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()
.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)
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()
app.root.get_screen('second_screen').function_to_trigger()
到
on_release:
按钮的
YES
。