[英]Kivy custom event propagation
我正在制作用於互聯網連接設備的Python / Kivy GUI。 由於該設備使用WAMP pub / sub方法進行通信,因此發生了很多同步事情。 問題是我不知道如何將自定義事件(例如on_connect,on_disconnect等)從kivy應用程序傳播到適當的kivy小部件。
這就是我現在所擁有的,為了獲得更好的可讀性,剝去了最低限度的要求,還有模擬連接事件的虛擬連接按鈕。
MyApp.py:
from kivy.app import App
from kivy.config import Config
from MainPage import MainPage
from AboutPage import AboutPage
from MainContainer import MainContainer
class MyApp(App):
def build(self):
self.container = MainContainer()
self.register_event_type('on_connect')
return self.container
def on_session(self, session):
print("session connected!")
self.session = session
self.dispatch('on_connect')
def on_connect(self, *args):
pass
MyApp().run()
my.kv:
#:kivy 1.10.1
#:import CardTransition kivy.uix.screenmanager.CardTransition
#:set menucolor1 0, 0.603, 0.784, 1
#:set menucolor2 0, 0.203, 0.384, 1
#:set backgroundcolor 0.95, 0.95, 0.95, 1
<MenuButton@Button>:
size_hint_y: None
height: 50
markup: True
<MenuSpacer@Label>:
size_hint_y: None
height: 3
canvas.before:
Color:
rgba: menucolor1
Rectangle:
pos: self.pos
size: self.size
<MainPage>:
canvas.before:
Color:
rgba: backgroundcolor
Rectangle:
pos: self.pos
size: self.size
name: 'main_screen'
Label:
color: menucolor1
text: "Hi I'm Main Screen"
<AboutPage>:
canvas:
Color:
rgba: backgroundcolor
Rectangle:
pos: self.pos
size: self.size
name: 'about_screen'
Label:
color: menucolor1
text: "Hi I'm About Screen"
<MainContainer>:
manager: manager
canvas:
Color:
rgba: backgroundcolor
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
size: root.size
orientation: 'horizontal'
BoxLayout:
orientation: 'vertical'
width: 150
size_hint_x: None
MenuButton:
text: '[b]Main[/b]'
on_press: root.switch_to('main_screen')
MenuSpacer:
MenuButton:
text: "[b]About[/b]"
on_press: root.switch_to('about_screen')
MenuSpacer:
MenuButton:
text: "[b]DummyConnect[/b]"
on_press: root.dummyconnect()
Widget:
canvas.before:
Color:
rgba: menucolor1
Rectangle:
pos: self.pos
size: self.size
ScreenManager:
id:manager
transition: CardTransition(direction='right',mode='push',duration=0.2)
MainPage:
AboutPage:
MainContainer.py
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.app import App
class MainContainer(Widget):
manager = ObjectProperty(None)
def __init__(self, **kwargs):
self.register_event_type('on_connect')
super(MainContainer,self).__init__(**kwargs)
print(self.children)
def switch_to(self,name):
self.manager.current = name
def on_connect(self, *args):
print("hello there")
def dummyconnect(self):
App.get_running_app().on_session("dummysession")
MainPage.py
from kivy.uix.screenmanager import Screen
class MainPage(Screen):
pass
AboutPage.py
from kivy.uix.screenmanager import Screen
class AboutPage(Screen):
pass
因此,基本上,我希望在MyApp中調度的on_connect事件傳播到MainPage和AboutPages,目前只有MainContainer定義了on_connect,但即使這樣也不會觸發。
我想我可以通過將其自己傳播給每個小部件的所有孩子來做到這一點,但是我還需要對所有的boxlayouts,screenmanagers和screen都實現它嗎? 我認為有更好的方法可以做到這一點,但我還沒有找到。
任何幫助表示贊賞!
要將on_connect傳播到所有屏幕,即MainPage和AboutPage。 有關詳細信息,請參閱示例。
return True
,表明我們已經消耗了觸摸並且不希望其進一步傳播。 我已注釋掉return True
以顯示事件傳播。 嘗試取消注釋return True
以顯示傳播已停止。
def __init__(self, **kwargs):
super(MainContainer, self).__init__(**kwargs)
self.register_event_type('on_connect')
print(self.children)
self.bind(on_connect=self.ids.main_page.on_connect)
self.bind(on_connect=self.ids.about_page.on_connect)
...
def on_connect(self, *args):
print("\nMainContainer.on_connect()")
print("hello there")
# return True # indicating that we have consumed the touch and don’t want it to propagate any further.
from kivy.app import App
from kivy.config import Config
from MainPage import MainPage
from AboutPage import AboutPage
from MainContainer import MainContainer
class MyApp(App):
def build(self):
return MainContainer()
if __name__ == "__main__":
MyApp().run()
#:kivy 1.10.1
#:import CardTransition kivy.uix.screenmanager.CardTransition
#:set menucolor1 0, 0.603, 0.784, 1
#:set menucolor2 0, 0.203, 0.384, 1
#:set backgroundcolor 0.95, 0.95, 0.95, 1
<MenuButton@Button>:
size_hint_y: None
height: 50
markup: True
<MenuSpacer@Label>:
size_hint_y: None
height: 3
canvas.before:
Color:
rgba: menucolor1
Rectangle:
pos: self.pos
size: self.size
<MainPage>:
canvas.before:
Color:
rgba: backgroundcolor
Rectangle:
pos: self.pos
size: self.size
name: 'main_screen'
Label:
color: menucolor1
text: "Hi I'm Main Screen"
<AboutPage>:
canvas:
Color:
rgba: backgroundcolor
Rectangle:
pos: self.pos
size: self.size
name: 'about_screen'
Label:
color: menucolor1
text: "Hi I'm About Screen"
<MainContainer>:
manager: manager
canvas:
Color:
rgba: backgroundcolor
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
size: root.size
orientation: 'horizontal'
BoxLayout:
orientation: 'vertical'
width: 150
size_hint_x: None
MenuButton:
text: '[b]Main[/b]'
on_press: root.switch_to('main_screen')
MenuSpacer:
MenuButton:
text: "[b]About[/b]"
on_press: root.switch_to('about_screen')
MenuSpacer:
MenuButton:
text: "[b]DummyConnect[/b]"
on_press:
root.on_session()
Widget:
canvas.before:
Color:
rgba: menucolor1
Rectangle:
pos: self.pos
size: self.size
ScreenManager:
id: manager
transition: CardTransition(direction='right',mode='push',duration=0.2)
MainPage:
id: main_page
AboutPage:
id: about_page
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
class MainContainer(Widget):
manager = ObjectProperty(None)
def __init__(self, **kwargs):
super(MainContainer, self).__init__(**kwargs)
self.register_event_type('on_connect')
print(self.children)
self.bind(on_connect=self.ids.main_page.on_connect)
self.bind(on_connect=self.ids.about_page.on_connect)
def switch_to(self, name):
self.manager.current = name
def on_connect(self, *args):
print("\nMainContainer.on_connect()")
print("hello there")
# return True # indicating that we have consumed the touch and don’t want it to propagate any further.
def on_session(self):
print("session connected!")
self.dispatch('on_connect')
from kivy.uix.screenmanager import Screen
class MainPage(Screen):
def on_connect(self, *args):
print("\nMainPage.on_connect()")
# return True # indicating that we have consumed the touch and don’t want it to propagate any further.
from kivy.uix.screenmanager import Screen
class AboutPage(Screen):
def on_connect(self, *args):
print("\nAboutPage.on_connect()")
# return True # indicating that we have consumed the touch and don’t want it to propagate any further.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.