软件设计讲解
2024-11-29
软件框架
软件设计图
业务系统启动流程
代码讲解
事件管理
各个模块之间通过 EventMap
事件管理类进行协作。EventMap
事件管理类提供事件的绑定、取绑以及消息的同步、异步发送。其定义如下:
class EventMap(object):
"""===example===
import EventMap
def time_out(event=None, msg=None):
pass
EventMap.bind("time_out", time_out)
EventMap.send("time_out")
"""
__event_map = dict()
__event_log = None
MODE_SYNC = 0
MODE_ASYNC = 1
def __init__(self):
pass
@classmethod
def bind(cls, event, callback):
"""
:param event: event name
:param callback: event callback
"""
if None == event or "" == event:
return
cls.__event_map[event] = callback
@classmethod
def unbind(cls, event):
"""
:param event: event name
"""
if None == event or "" == event:
return
cls.__event_map.pop(event, None)
@classmethod
def send(cls, event, msg=None, mode=MODE_SYNC):
"""
:param event: event name
:param msg: event message
:param mode: send mode, sync or async
"""
if event not in cls.__event_map:
return
if cls.MODE_SYNC == mode:
res = None
try:
if event in cls.__event_map:
res = cls.__event_map[event](event, msg)
except Exception as e:
if cls.__event_log:
cls.__event_log.info("ERROR executed (event) -> {} (params) -> {} (result) -> {}".format(event, msg, res))
usys.print_exception(e)
if cls.__event_log:
cls.__event_log.info("SYNC executed (event) -> {} (params) -> {} (result) -> {}".format(event, msg, res))
return res
elif cls.MODE_ASYNC == mode:
try:
_thread.start_new_thread(cls.__event_map[event], (event, msg))
except Exception as e:
if cls.__event_log:
cls.__event_log.info("ERROR executed (event) -> {} (params) -> {} (result) -> {}".format(event, msg, res))
usys.print_exception(e)
if cls.__event_log:
cls.__event_log.info("ASYNC executed (event) -> {} (params) -> {} (result) -> {}".format(event, msg, None))
抽象加载
common.py
提供了一个名为 AbstractLoad
的抽象加载基类,方便用户理解界面加载的过程,定义如下:
class AbstractLoad(object):
def load_before(self, *args, **kwargs):
"""加载前调用"""
pass
def load(self, *args, **kwargs):
"""加载时调用"""
pass
def load_after(self, *args, **kwargs):
"""加载后调用"""
pass
def instance_after(self, *args, **kwargs):
"""实例化后调用"""
pass
def deactivate(self, *args, **kwargs):
"""失效"""
pass
AbstractLoad
抽象加载基类会被定义的 UI 界面和 services
所继承,在加载 UI 界面或加载服务时可以调用对应的抽象类方法,实现页面和服务的加载。
比如在主界面的定义中,可以在 load
方法中添加相应的代码实现主界面的布局与样式,这样在进入主界面后就能显示出设置的 UI 界面了。
服务模块
services.py
定义了多个 service
,用于提供各种服务。这些 servies
继承 AbstractLoad
抽象加载基类,便于在加载过程中提供各类服务事项。
DevInfoService
:提供设备信息服务MediaService
:提供音频服务NetService
:提供网络服务PocService
:提供 Poc 对讲服务
各 service
之间的关系如下图:
如用户需添加
service
,可参考已有service
样式进行添加,并添加到poc_main.py
中对应的位置即可。
界面模块
ui.py
定义了一个 Screen
基类,该基类被定义的 UI 界面继承,用于约束 UI 界面的接口定义,其定义如下:
class Screen(AbstractLoad):
class Type():
Init = "init"
Normal = "normal" # 默认
MenuBar = "menubar"
ToolBar = "toolbar"
StatusBar = "statusbar"
def __init__(self):
self.meta = None # lvgl meta object
self.meta_info = {}
self.last_screen = None
def set_last_screen(self, name):
self.last_screen = name
def load_before(self):
pass
def load(self):
pass
def load_after(self):
pass
def instance_after(self):
pass
def deactivate(self):
pass
def key2_once_click(self):
pass
def key2_double_click(self):
pass
def key2_long_press(self):
pass
def prev_idx(self, now_idx, count):
cur_idx = now_idx - 1
if cur_idx < 0:
cur_idx = count - 1
return cur_idx
def next_idx(self, now_idx, count):
cur_idx = now_idx + 1
if cur_idx > count - 1:
cur_idx = 0
return cur_idx
在 ui.py
中,还定义了多个 UI 界面,如:
PocUI
:主 UI,提供MenuBar
、PromptBox
和Screen
的管理以及按键事件的响应处理MenuBar
:菜单栏PromptBox
:提示框Screen
:UI 屏幕,也可以理解为 UI 界面,用于展示给用户看的各种界面。如MenuBar
、WelcomeScreen
和MemberScreen
等
各 UI 界面之间的关系如下图:
如用户需添加
Screen
,可参考已有Screen
样式进行添加,并添加到poc_main.py
中对应的位置即可。
APP管理
poc_main.py
中使用一个 APP
类进行管理,用户添加或修改如按键、消息框和服务等操作,调用相应的函数添加即可。
#=== 1.添加按键 ===
App.add_key(KeyManger())
#=== 2.添加主UI ===
App.set_ui(PocUI())
#=== 3.添加屏幕栏 ===
App.add_bar(MenuBar())
#=== 4.添加消息框 ===
App.add_msgbox(PromptBox())
#=== 5.添加UI屏幕 ===
App.add_screen( MenuBar()) \
.add_screen( MainScreen()) \
.add_screen( WelcomeScreen() ) \
.add_screen( PromptBox() ) \
.add_screen( MemberScreen() ) \
.add_screen( GroupScreen() ) \
.add_screen( SettingScreen() ) \
.add_screen( DeviceScreen() ) \
.add_screen( ICCIDScreen() ) \
.add_screen( IMEIScreen()) \
.add_screen( FirmwareScreen() )
#=== 6.添加服务 ===
App.add_service( NetService()) \
.add_service( PocService()) \
.add_service( MediaService()) \
.add_service( DevInfoService() )
#=== 7.运行App ===
App.exec()