Welcome to K230 Vision Module repository
03.Application Discovery Mechanism in GUI
Application Discovery and Management Core
1. Course Objectives
After the GUI system starts, where do the desktop icons come from? Why can the system recognize it when we put a folder in the SD card? In this lesson, we will introduce the "application discovery" mechanism of AppManager.
2. Core Source Code Analysis
File Path: src/canmv/port/builtin_py/ybMain/main.py
The scan_apps method in AppManager (around line 689) is responsible for scanning and loading applications. This method demonstrates how to achieve pluginization through Python's dynamic features.
2.1 Application Storage Structure
All applications are stored in the /sdcard/apps/ directory. This is a typical plugin-based structure.
xxxxxxxxxx/sdcard/apps/├── camera/ <-- This is an App│ ├── app.py <-- Code entry point│ └── icon.png <-- Desktop icon├── setting/ <-- This is another App│ ├── app.py│ └── icon.png└── ...2.2 Dynamic Loading Principle
The loading process of standard plugins (apps) is as follows:
- Traverse Directory: When the system starts,
AppManagerwill list all subdirectories under theappsdirectory. - Verify Legitimacy: Check if there is
app.pyin the folder. - Import Module: Use Python's
importmechanism to dynamically loadapp.py. - Instantiate: Each
app.pycontains anAppclass, the system will create its instance and add it to the management list.
2.3 Application Registration and Icon Creation (register_app & create_app_icon)
After the application is instantiated, it will be added to the self.apps dictionary. Subsequently, AppManager will call create_app_icon to draw desktop icons.
This function is not just about drawing an image, it also contains exquisite animation logic:
Color Generation:
- If the App comes with its own
icon, use the image. - If there is no image but
coloris defined, automatically generate a gradient background. - If there is nothing, select colors from a preset iOS-style palette in rotation.
- If the App comes with its own
Entrance Animation:
- We use
lv.anim_tto create three concurrent animations: icon grows from small to large (size_anim), icon fades in (opa_anim), text fades in (label_anim). - Wave Effect:
delay_ms = (row * self.icons_per_row + col) * 20. By calculating delay time based on row and column positions, icons pop up one by one like waves.
- We use
2.4 Implementation of Page Turning Logic (change_page)
When the number of applications exceeds one page, or when the user swipes the screen, page turning is needed. The implementation logic of page turning is very concise and effective:
Clear Old Page:
- Traverse all child objects on the main screen (
self.home_screen). - Determine whether the child object is within the "application grid area" through coordinates.
- If it's an application icon (not status bar or Dock), directly
delete()it.
xxxxxxxxxx# Pseudocode logicfor child in home_screen.children:if child.y >= grid_start_y:child.delete()- Traverse all child objects on the main screen (
Create New Page:
- Update
self.current_pagevariable. - Re-traverse all Apps, calculate whether they should be displayed on the new page.
- If they should be displayed, call
create_app_iconagain, which means each page turn will trigger a cool icon popup animation.
app_page = (app_index) // self.apps_per_page + 1if app_page == page_number:self.create_app_icon(self.apps[app_name])- Update