Пользовательское распространение событий Kivy
Я делаю графический интерфейс Python/Kivy для подключенного к Интернету устройства. Происходит много синхронизации, так как устройство использует для связи метод 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
Поэтому в основном я хотел бы, чтобы событие on_connect, отправляемое в MyApp, распространялось на MainPage и AboutPages, в настоящее время только MainContainer определил on_connect, но даже это не срабатывает.
Я думаю, я мог бы сделать это, распространяя это сам для всех детей в каждом виджете, но мне нужно было бы внедрить это также для всех box-макетов, экранных менеджеров и экранов? Я думаю, что есть лучший способ сделать это, но я еще не нашел его.
Любая помощь приветствуется!
1 ответ
Решение
Распространение on_connect на все экраны, т.е. MainPage и AboutPage. Пожалуйста, обратитесь к примеру для деталей.
- Добавлены идентификаторы для MainPage и AboutPage
- Привязать к ним обратные вызовы. Когда событие отправляется, ваши обратные вызовы будут вызываться с параметрами, относящимися к этому конкретному событию.
return True
, указывая на то, что мы поглотили прикосновение и не хотим, чтобы оно распространялось дальше.- Удалены коды в App (main.py) и добавлены некоторые в MainContainer.py
Заметка
Я прокомментировал return True
показать распространение события. Попробуйте раскомментировать return True
чтобы показать распространение остановлено.
обрывки
MainContainer
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.
пример
main.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):
return MainContainer()
if __name__ == "__main__":
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.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
MainContainer.py
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')
MainPage.py
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.
AboutPage
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.