📚 راهنمای کامل ماژول LVGL برای EVM – نسخه مدیریت حافظه
🎯 معرفی ماژول LVGL
ماژول LVGL امکان ایجاد رابط کاربری گرافیکی روی ESP32 را برای ماشین مجازی جاوا برای امبدد بردها را فراهم میکند. این ماژول تمام ویجتهای اصلی LVGL را پشتیبانی میکند.
🏗️ ساختار اصلی
ایجاد و مدیریت آبجکتها
// ایجاد صفحه اصلی let screen = lv.lv_scr_act(); // ایجاد آبجکت جدید let obj = lv.lv_obj_create(screen); // تنظیم موقعیت و سایز lv.lv_obj_set_pos(obj, 10, 20); lv.lv_obj_set_size(obj, 100, 50);
🔥 مدیریت حافظه و تخریب آبجکتها (جدید)
تخریب ایمن آبجکتها
// 🔥 روش صحیح تخریب آبجکت let obj = lv.lv_obj_create(screen); let style = lv.lv_style_create(); // تنظیم استایل و خصوصیات lv.lv_obj_add_style(obj, style, 0); // 🔥 تخریب صحیح آبجکت و استایل lv.destroy_obj({ nativePtr: obj, stylePtr: style }); console.log("Object destroyed successfully!");
پاکسازی کامل تمام آبجکتها
// 🔥 پاکسازی ایمن تمام آبجکتهای صفحه let count = lv.safe_destroy_all(); console.log("Destroyed " + count + " objects"); // 🔥 پاکسازی انتخابی let parent = lv.lv_obj_create(screen); // ایجاد چندین child let child1 = lv.lv_obj_create(parent); let child2 = lv.lv_obj_create(parent); // پاکسازی تمام children های یک parent lv.lv_obj_delete_all_children(parent);
توابع جدید مدیریت حافظه
// بررسی valid بودن آبجکت if (lv.lv_obj_is_valid(obj)) { console.log("Object is valid"); } else { console.log("Object is invalid"); } // تخریب فوری آبجکت lv.lv_obj_del(obj); // تخریب غیرهمزمان (برای جلوگیری از deadlock) lv.lv_obj_del_async(obj); // پاکسازی استایل lv.lv_style_destroy(style);
🎨 مدیریت استایلها
ترتیب صحیح کار با LVGL:
- ایجاد استایل
- مقداردهی اولیه استایل (
init_style) - تنظیم خصوصیات استایل
- اعمال استایل به آبجکت
- تخریب استایل وقتی نیاز نیست
// ایجاد و مقداردهی استایل
let style = lv.lv_style_create();
lv.init_style(style); // 🔥 تابع جدید برای مقداردهی اولیه
// تنظیم خصوصیات
lv.set_style_bg_color(style, lv.lv_color_hex(0xFF0000));
lv.set_style_bg_opa(style, lv.LV_OPA_COVER);
lv.set_style_radius(style, 10);
// اعمال استایل
lv.lv_obj_add_style(obj, style, 0);
// 🔥 وقتی کارمان تمام شد:
lv.destroy_obj({
nativePtr: obj,
stylePtr: style
});پالت رنگهای پیشفرض
// استفاده از پالتهای پیشفرض let red = lv.lv_palette_main(lv.LV_PALETTE_RED); let blue = lv.lv_palette_main(lv.LV_PALETTE_BLUE); let green = lv.lv_palette_main(lv.LV_PALETTE_GREEN); // تبدیل RGB به رنگ LVGL let customColor = lv.rgba_to_color(1.0, 0.5, 0.0, 1.0); // 🔥 تابع جدید
📋 ویجتهای اصلی
۱. Label (متن)
// ایجاد لیبل let label = lv.lv_label_create(screen); // تنظیم متن lv.lv_label_set_text(label, "Hello EVM!"); // تنظیم متن طولانی با اتوماتیک برش lv.lv_label_set_long_mode(label, lv.LV_LABEL_LONG_SCROLL_CIRCULAR); // تنظیم موقعیت lv.lv_obj_set_pos(label, 10, 10); // تنظیم استایل متن let textStyle = lv.lv_style_create(); lv.init_style(textStyle); lv.set_style_text_color(textStyle, lv.lv_color_hex(0xFFFFFF)); lv.set_style_text_font(textStyle, lv.lvgl_style_get_font(16)); // 🔥 انتخاب فونت lv.lv_obj_add_style(label, textStyle, 0); // 🔥 مدیریت حافظه // بعد از استفاده: lv.destroy_obj({ nativePtr: label, stylePtr: textStyle });
۲. Button (دکمه)
// ایجاد دکمه let btn = lv.lv_btn_create(screen); lv.lv_obj_set_size(btn, 80, 40); lv.lv_obj_set_pos(btn, 50, 100); // اضافه کردن متن روی دکمه let btnLabel = lv.lv_label_create(btn); lv.lv_label_set_text(btnLabel, "Click Me!"); lv.lv_obj_center(btnLabel); // استایل دکمه let btnStyle = lv.lv_style_create(); lv.init_style(btnStyle); lv.set_style_bg_color(btnStyle, lv.lv_palette_main(lv.LV_PALETTE_BLUE)); lv.set_style_bg_opa(btnStyle, lv.LV_OPA_COVER); lv.set_style_radius(btnStyle, 10); lv.lv_obj_add_style(btn, btnStyle, 0); // 🔥 ثبت event با مدیریت حافظه lv.lv_obj_add_event_cb(btn, function(obj, event) { console.log("Button clicked! Event:", event); }, lv.LV_EVENT_CLICKED); // 🔥 تخریب ایمن lv.destroy_obj({ nativePtr: btn, stylePtr: btnStyle });
۳. Slider (اسلایدر)
// ایجاد اسلایدر let slider = lv.lv_slider_create(screen); lv.lv_obj_set_size(slider, 150, 10); lv.lv_obj_set_pos(slider, 20, 60); // تنظیم محدوده lv.lv_slider_set_range(slider, 0, 100); // تنظیم مقدار اولیه lv.lv_slider_set_value(slider, 50, lv.LV_ANIM_OFF); // استایل اسلایدر let sliderStyle = lv.lv_style_create(); lv.init_style(sliderStyle); lv.set_style_bg_color(sliderStyle, lv.lv_palette_main(lv.LV_PALETTE_GREY)); lv.set_style_bg_opa(sliderStyle, lv.LV_OPA_50); lv.set_style_outline_width(sliderStyle, 0); lv.lv_obj_add_style(slider, sliderStyle, 0); // event برای تغییر مقدار lv.lv_obj_add_event_cb(slider, function(obj, event) { let value = lv.lv_slider_get_value(obj); console.log("Slider value:", value); }, lv.LV_EVENT_VALUE_CHANGED);
۴. Switch (سوییچ)
// ایجاد سوییچ let sw = lv.lv_switch_create(screen); lv.lv_obj_set_pos(sw, 20, 160); // استایل سوییچ let switchStyle = lv.lv_style_create(); lv.init_style(switchStyle); lv.set_style_bg_color(switchStyle, lv.lv_palette_main(lv.LV_PALETTE_GREEN)); lv.lv_obj_add_style(sw, switchStyle, 0); // event برای تغییر وضعیت lv.lv_obj_add_event_cb(sw, function(obj, event) { let isOn = lv.lv_obj_has_state(obj, lv.LV_STATE_CHECKED); console.log("Switch is:", isOn ? "ON" : "OFF"); }, lv.LV_EVENT_VALUE_CHANGED);
۵. Checkbox (چکباکس)
// ایجاد چکباکس let cb = lv.lv_checkbox_create(screen); lv.lv_obj_set_pos(cb, 20, 200); lv.lv_checkbox_set_text(cb, "Enable Feature"); // استایل چکباکس let checkboxStyle = lv.lv_style_create(); lv.init_style(checkboxStyle); lv.set_style_text_color(checkboxStyle, lv.lv_color_hex(0x333333)); lv.lv_obj_add_style(cb, checkboxStyle, 0); // event برای تغییر وضعیت lv.lv_obj_add_event_cb(cb, function(obj, event) { let isChecked = lv.lv_obj_has_state(obj, lv.LV_STATE_CHECKED); console.log("Checkbox is:", isChecked ? "checked" : "unchecked"); }, lv.LV_EVENT_VALUE_CHANGED);
۶. Dropdown (لیست کشویی)
// ایجاد dropdown let dropdown = lv.lv_dropdown_create(screen); lv.lv_obj_set_pos(dropdown, 20, 240); lv.lv_obj_set_size(dropdown, 120, 40); // تنظیم گزینهها lv.lv_dropdown_set_options(dropdown, "Option 1\nOption 2\nOption 3\nOption 4"); // استایل dropdown let dropdownStyle = lv.lv_style_create(); lv.init_style(dropdownStyle); lv.set_style_bg_color(dropdownStyle, lv.lv_color_hex(0xF0F0F0)); lv.set_style_border_width(dropdownStyle, 1); lv.set_style_border_color(dropdownStyle, lv.lv_color_hex(0xCCCCCC)); lv.lv_obj_add_style(dropdown, dropdownStyle, 0); // event برای انتخاب گزینه lv.lv_obj_add_event_cb(dropdown, function(obj, event) { let selected = lv.lv_dropdown_get_selected(obj); console.log("Selected option:", selected); }, lv.LV_EVENT_VALUE_CHANGED);
۷. Textarea (ورودی متن)
// ایجاد textarea let ta = lv.lv_textarea_create(screen); lv.lv_obj_set_size(ta, 200, 60); lv.lv_obj_set_pos(ta, 20, 280); // تنظیم placeholder lv.lv_textarea_set_placeholder_text(ta, "Enter text here..."); // تنظیم متن تک خطی lv.lv_textarea_set_one_line(ta, true); // استایل textarea let textareaStyle = lv.lv_style_create(); lv.init_style(textareaStyle); lv.set_style_bg_color(textareaStyle, lv.lv_color_hex(0xFFFFFF)); lv.set_style_border_width(textareaStyle, 1); lv.set_style_border_color(textareaStyle, lv.lv_color_hex(0xCCCCCC)); lv.set_style_pad_all(textareaStyle, 8); lv.lv_obj_add_style(ta, textareaStyle, 0); // event برای تغییر متن lv.lv_obj_add_event_cb(ta, function(obj, event) { let text = lv.lv_textarea_get_text(obj); console.log("Textarea content:", text); }, lv.LV_EVENT_VALUE_CHANGED);
📊 ویجتهای پیشرفته
Arc (پیشرفت دایرهای)
// ایجاد arc let arc = lv.lv_arc_create(screen); lv.lv_obj_set_size(arc, 100, 100); lv.lv_obj_set_pos(arc, 50, 50); // تنظیم محدوده و مقدار lv.lv_arc_set_range(arc, 0, 100); lv.lv_arc_set_value(arc, 75); // تنظیم زوایا lv.lv_arc_set_bg_angles(arc, 0, 270); // استایل arc let arcStyle = lv.lv_style_create(); lv.init_style(arcStyle); lv.set_style_arc_color(arcStyle, lv.lv_palette_main(lv.LV_PALETTE_BLUE)); lv.set_style_arc_width(arcStyle, 8); lv.lv_obj_add_style(arc, arcStyle, 0);
Bar (نوار پیشرفت)
// ایجاد bar let bar = lv.lv_bar_create(screen); lv.lv_obj_set_size(bar, 200, 20); lv.lv_obj_set_pos(bar, 20, 120); // تنظیم محدوده و مقدار lv.lv_bar_set_range(bar, 0, 100); lv.lv_bar_set_value(bar, 60, lv.LV_ANIM_ON); // استایل bar let barStyle = lv.lv_style_create(); lv.init_style(barStyle); lv.set_style_bg_color(barStyle, lv.lv_palette_main(lv.LV_PALETTE_GREEN)); lv.set_style_bg_opa(barStyle, lv.LV_OPA_COVER); lv.lv_obj_add_style(bar, barStyle, 0);
Roller (غلتک)
// ایجاد roller let roller = lv.lv_roller_create(screen); lv.lv_obj_set_pos(roller, 20, 300); lv.lv_obj_set_size(roller, 100, 120); // تنظیم گزینهها lv.lv_roller_set_options(roller, "January\nFebruary\nMarch\nApril\nMay\nJune\nJuly\nAugust\nSeptember\nOctober\nNovember\nDecember", lv.LV_ROLLER_MODE_NORMAL); // تنظیم سطرهای قابل مشاهده lv.lv_roller_set_visible_row_count(roller, 3); // event برای انتخاب lv.lv_obj_add_event_cb(roller, function(obj, event) { let selected = lv.lv_roller_get_selected(obj); let text = lv.lv_roller_get_options(obj).split('\n')[selected]; console.log("Selected month:", text); }, lv.LV_EVENT_VALUE_CHANGED);
Spinner (لودر چرخان)
// ایجاد spinner let spinner = lv.lv_spinner_create(screen, 1000, 60); lv.lv_obj_set_size(spinner, 50, 50); lv.lv_obj_set_pos(spinner, 100, 100); // استایل spinner let spinnerStyle = lv.lv_style_create(); lv.init_style(spinnerStyle); lv.set_style_arc_color(spinnerStyle, lv.lv_palette_main(lv.LV_PALETTE_BLUE)); lv.set_style_arc_width(spinnerStyle, 6); lv.lv_obj_add_style(spinner, spinnerStyle, 0);
🎨 مدیریت تصاویر با کش
// 🔥 سیستم کش تصاویر let imgDesc = image.png_decode("images/logo.png"); // 🔥 کش خودکار let img = lv.lv_img_create(screen); lv.lv_img_set_src(img, imgDesc); lv.lv_obj_set_pos(img, 50, 50); // بررسی وجود فایل if (image.file_exists("images/logo.png")) { console.log("File exists!"); } // تنظیم pivot برای تصاویر let pivot = [25, 25]; lv.lv_img_set_pivot(img, pivot); // 🔥 تخریب تصویر وقتی نیاز نیست image.png_destroy(imgDesc); // 🔥 مدیریت کش تصاویر let cacheInfo = image.get_cache_info(); console.log("Cache hits:", cacheInfo.hits, "Misses:", cacheInfo.misses); // پاکسازی کش image.clear_image_cache();
🎨 مدیریت تصاویر
نمایش تصاویر
// ایجاد آبجکت تصویر let img = lv.lv_img_create(screen); lv.lv_obj_set_pos(img, 50, 50); // تنظیم منبع تصویر (از SPIFFS) lv.lv_img_set_src(img, "A:/images/logo.png"); // تنظیم opacity lv.lv_obj_set_style_img_opa(img, lv.LV_OPA_70, 0);
ترنسفورمیشن تصاویر
// چرخش تصویر lv.lv_img_set_angle(img, 45); // 45 درجه // زوم lv.lv_img_set_zoom(img, 256); // 100% (256 = 1.0) // جابجایی lv.lv_img_set_offset_x(img, 10); lv.lv_img_set_offset_y(img, -5);
🏗️ Layout و Flexbox
Flex Layout
// تنظیم flex flow lv.lv_obj_set_flex_flow(parent, lv.LV_FLEX_FLOW_ROW_WRAP); // تنظیم alignment lv.lv_obj_set_style_flex_main_place(parent, lv.LV_FLEX_ALIGN_SPACE_EVENLY, 0); lv.lv_obj_set_style_flex_cross_place(parent, lv.LV_FLEX_ALIGN_CENTER, 0); // تنظیم grow برای آبجکتها lv.lv_obj_set_flex_grow(child1, 1); lv.lv_obj_set_flex_grow(child2, 2); // دو برابر child1
انواع Flex Flow
lv.LV_FLEX_FLOW_ROW // ردیف lv.LV_FLEX_FLOW_COLUMN // ستون lv.LV_FLEX_FLOW_ROW_WRAP // ردیف با wrap lv.LV_FLEX_FLOW_COLUMN_WRAP // ستون با wrap lv.LV_FLEX_FLOW_ROW_REVERSE // ردیف معکوس
⚡ مدیریت State و Flags
مدیریت State
// اضافه کردن state lv.lv_obj_add_state(obj, lv.LV_STATE_CHECKED); lv.lv_obj_add_state(obj, lv.LV_STATE_DISABLED); // حذف state lv.lv_obj_clear_state(obj, lv.LV_STATE_DISABLED); // بررسی state let isChecked = lv.lv_obj_has_state(obj, lv.LV_STATE_CHECKED);
مدیریت Flags
// اضافه کردن flag lv.lv_obj_add_flag(obj, lv.LV_OBJ_FLAG_CLICKABLE); lv.lv_obj_add_flag(obj, lv.LV_OBJ_FLAG_SCROLLABLE); // حذف flag lv.lv_obj_clear_flag(obj, lv.LV_OBJ_FLAG_SCROLLABLE); // بررسی flag let isClickable = lv.lv_obj_has_flag(obj, lv.LV_OBJ_FLAG_CLICKABLE);
⏰ مدیریت تایمرها (جدید)
تایمرهای setTimeout/setInterval
// 🔥 setTimeout با مدیریت حافظه let timer1 = setTimeout(function() { console.log("Timeout executed!"); }, 1000); // 🔥 setInterval let timer2 = setInterval(function() { console.log("Interval tick!"); }, 2000); // 🔥 حذف تایمرها clearTimeout(timer1); clearInterval(timer2);
🎯 مدیریت موقعیت و Alignment
تراز کردن آبجکتها
// تراز مرکزی lv.lv_obj_center(obj); // تراز نسبی lv.lv_obj_align(obj, lv.LV_ALIGN_TOP_LEFT, 10, 10); lv.lv_obj_align(obj, lv.LV_ALIGN_BOTTOM_RIGHT, -10, -10); // تراز نسبت به آبجکت دیگر let parent = lv.lv_obj_create(screen); let child = lv.lv_obj_create(parent); lv.lv_obj_align_to(child, parent, lv.LV_ALIGN_CENTER, 0, 0);
ثابتهای Alignment
// انواع تراز lv.LV_ALIGN_TOP_LEFT lv.LV_ALIGN_TOP_MID lv.LV_ALIGN_TOP_RIGHT lv.LV_ALIGN_BOTTOM_LEFT lv.LV_ALIGN_BOTTOM_MID lv.LV_ALIGN_BOTTOM_RIGHT lv.LV_ALIGN_LEFT_MID lv.LV_ALIGN_RIGHT_MID lv.LV_ALIGN_CENTER
🔄 انیمیشن و Effects
انیمیشنهای ساده
// fade in lv.lv_obj_fade_in(obj, 1000, 0); // 1000ms delay // fade out lv.lv_obj_fade_out(obj, 1000, 0); // حذف تمام انیمیشنها lv.lv_anim_del_all();
ترنسفورمیشنها
// چرخش lv.lv_style_set_transform_angle(style, 45); // 45 درجه // مقیاس lv.lv_style_set_transform_zoom(style, 1.5); // 150% // موقعیت lv.lv_style_set_translate_x(style, 10); lv.lv_style_set_translate_y(style, -5);
🎮 مدیریت رویدادها با مدیریت حافظه
ثبت event handler ایمن
// 🔥 ثبت event با مدیریت حافظه lv.lv_obj_add_event_cb(btn, function(obj, event) { console.log("Event:", event); console.log("Position:", lv.indev_get_x(), lv.indev_get_y()); // 🔥 توابع جدید }, lv.LV_EVENT_CLICKED); // 🔥 حذف event lv.lv_obj_remove_event_cb(btn); // 🔥 حذف تمام eventهای یک آبجکت lv.lv_obj_remove_all_event_cb(btn); // 🔥 گرفتن اطلاعات eventهای فعال let eventInfo = lv.get_active_events_info(); console.log("Active events:", eventInfo.count);
انواع رویدادها
lv.LV_EVENT_PRESSED lv.LV_EVENT_RELEASED lv.LV_EVENT_CLICKED lv.LV_EVENT_VALUE_CHANGED lv.LV_EVENT_FOCUSED lv.LV_EVENT_DEFOCUSED
📱 مدیریت صفحه نمایش
اطلاعات صفحه نمایش
// 🔥 توابع جدید برای اندازه صفحه let screenWidth = lv.get_screen_width(); let screenHeight = lv.get_screen_height(); console.log("Screen size:", screenWidth, "x", screenHeight); // 🔥 چرخش صفحه نمایش lv.disp_set_rotation(0); // 0-3 (0°, 90°, 180°, 270°)
موقعیتیابی پیشرفته
// 🔥 گرفتن موقعیت مطلق let absX = lv.lv_obj_get_abs_x(obj); let absY = lv.lv_obj_get_abs_y(obj); // تنظیم pivot برای تصاویر let pivot = [50, 50]; lv.lv_img_set_pivot(img, pivot);
🎯 مثال کامل با مدیریت حافظه
برنامه نمونه – کنترل پنل با مدیریت حافظه
class UIController { constructor() { this.screen = lv.lv_scr_act(); this.objects = []; this.styles = []; this.initUI(); } initUI() { // ایجاد دکمهها this.createButton("Start", 50, 30, this.onButtonClick.bind(this)); this.createButton("Stop", 180, 30, this.onButtonClick.bind(this)); // ایجاد اسلایدر this.createSlider(20, 100, this.onSliderChange.bind(this)); // ایجاد سوییچ this.createSwitch(20, 150, this.onSwitchChange.bind(this)); // ایجاد چکباکس this.createCheckbox(20, 200, "Enable Feature", this.onCheckboxChange.bind(this)); } createButton(text, x, y, callback) { let style = lv.lv_style_create(); lv.init_style(style); lv.set_style_bg_color(style, lv.lv_palette_main(lv.LV_PALETTE_BLUE)); lv.set_style_radius(style, 10); let btn = lv.lv_btn_create(this.screen); lv.lv_obj_set_size(btn, 120, 50); lv.lv_obj_set_pos(btn, x, y); lv.lv_obj_add_style(btn, style, 0); let label = lv.lv_label_create(btn); lv.lv_label_set_text(label, text); lv.lv_obj_center(label); // ثبت event lv.lv_obj_add_event_cb(btn, callback, lv.LV_EVENT_CLICKED); this.objects.push(btn); this.styles.push(style); return { obj: btn, style: style }; } createSlider(x, y, callback) { let slider = lv.lv_slider_create(this.screen); lv.lv_obj_set_size(slider, 200, 20); lv.lv_obj_set_pos(slider, x, y); lv.lv_slider_set_range(slider, 0, 100); lv.lv_slider_set_value(slider, 50, lv.LV_ANIM_OFF); lv.lv_obj_add_event_cb(slider, callback, lv.LV_EVENT_VALUE_CHANGED); this.objects.push(slider); return slider; } createSwitch(x, y, callback) { let sw = lv.lv_switch_create(this.screen); lv.lv_obj_set_pos(sw, x, y); lv.lv_obj_add_event_cb(sw, callback, lv.LV_EVENT_VALUE_CHANGED); this.objects.push(sw); return sw; } createCheckbox(x, y, text, callback) { let cb = lv.lv_checkbox_create(this.screen); lv.lv_obj_set_pos(cb, x, y); lv.lv_checkbox_set_text(cb, text); lv.lv_obj_add_event_cb(cb, callback, lv.LV_EVENT_VALUE_CHANGED); this.objects.push(cb); return cb; } // Event handlers onButtonClick(obj, event) { let text = lv.lv_label_get_text(lv.lv_obj_get_child(obj, 0)); console.log("Button clicked:", text); } onSliderChange(obj, event) { let value = lv.lv_slider_get_value(obj); console.log("Slider value:", value); } onSwitchChange(obj, event) { let isOn = lv.lv_obj_has_state(obj, lv.LV_STATE_CHECKED); console.log("Switch is:", isOn ? "ON" : "OFF"); } onCheckboxChange(obj, event) { let isChecked = lv.lv_obj_has_state(obj, lv.LV_STATE_CHECKED); console.log("Checkbox is:", isChecked ? "checked" : "unchecked"); } destroyAll() { // 🔥 تخریب تمام آبجکتها به صورت ایمن this.objects.forEach((obj, index) => { if (this.styles[index]) { lv.destroy_obj({ nativePtr: obj, stylePtr: this.styles[index] }); } else { lv.lv_obj_del(obj); } }); this.objects = []; this.styles = []; // 🔥 پاکسازی باقیماندهها let count = lv.safe_destroy_all(); console.log("Total destroyed:", count); } } // استفاده از کلاس let ui = new UIController(); // وقتی برنامه تمام شد: // ui.destroyAll();
🔧 الگوهای مدیریت حافظه
الگوی ۱: مدیریت دستی
function createTemporaryUI() { let tempObj = lv.lv_obj_create(screen); let tempStyle = lv.lv_style_create(); lv.init_style(tempStyle); // استفاده از آبجکت // 🔥 تخریب وقتی کار تمام شد return function cleanup() { lv.destroy_obj({ nativePtr: tempObj, stylePtr: tempStyle }); }; } let cleanup = createTemporaryUI(); // بعد از استفاده: cleanup();
الگوی ۲: مدیریت خودکار با کلاس
class ManagedObject { constructor(parent) { this.obj = lv.lv_obj_create(parent); this.style = lv.lv_style_create(); lv.init_style(this.style); lv.lv_obj_add_style(this.obj, this.style, 0); } destroy() { lv.destroy_obj({ nativePtr: this.obj, stylePtr: this.style }); this.obj = null; this.style = null; } // وقتی آبجکت از scope خارج میشود __destruct() { if (this.obj) this.destroy(); } }
🚨 نکات مهم مدیریت حافظه
کارهای ضروری
// ✅ همیشه استایلها را مقداردهی اولیه کنید lv.init_style(style); // ✅ همیشه از destroy_obj استفاده کنید lv.destroy_obj({ nativePtr: obj, stylePtr: style }); // ✅ eventها را حذف کنید وقتی نیاز نیستند lv.lv_obj_remove_event_cb(obj); // ✅ تایمرها را حذف کنید clearTimeout(timer);
کارهای ممنوع
// ❌ هرگز مستقیماً حافظه را آزاد نکنید // lv_mem_free(obj); // اشتباه! // ❌ آبجکتها را بدون حذف event رها نکنید // ❌ استایلهای استفاده شده را مستقیماً حذف نکنید
بررسی سلامت حافظه
// بررسی وضعیت کش تصاویر let cacheInfo = image.get_cache_info(); console.log("Image cache:", cacheInfo); // بررسی eventهای فعال let eventInfo = lv.get_active_events_info(); console.log("Active events:", eventInfo.count); // بررسی valid بودن آبجکتها if (lv.lv_obj_is_valid(obj)) { console.log("Object is healthy"); }
📊 ثابتهای جدید
مدیریت حافظه
// ماکزیمم سایز کش تصاویر image.MAX_CACHE_SIZE = 10; // انواع فونتهای قابل انتخاب lv.lvgl_style_get_font(8); // فونت 8px lv.lvgl_style_get_font(12); // فونت 12px lv.lvgl_style_get_font(16); // فونت 16px lv.lvgl_style_get_font(20); // فونت 20px (پیشفرض) lv.lvgl_style_get_font(24); // فونت 24px
🔧 نکات مهم و بهترین روشها
// پاکسازی استایلها وقتی استفاده نمیشوند // lv.lv_style_reset(style); // در LVGL 8.3+ // استفاده از استایلهای مشترک برای آبجکتهای مشابه
بهینهسازی عملکرد
// غیرفعال کردن scroll برای آبجکتهای ساده lv.lv_obj_clear_flag(obj, lv.LV_OBJ_FLAG_SCROLLABLE); // استفاده از انیمیشن فقط وقتی لازم است lv.lv_slider_set_value(slider, 75, lv.LV_ANIM_OFF); // بدون انیمیشن
عیبیابی
// بررسی visibility let isVisible = lv.lv_obj_is_visible(obj); // بررسی موقعیت و سایز let x = lv.lv_obj_get_x(obj); let y = lv.lv_obj_get_y(obj); let width = lv.lv_obj_get_width(obj); let height = lv.lv_obj_get_height(obj);
🎨 پالت رنگهای کامل
// تمام پالتهای رنگی موجود lv.LV_PALETTE_RED lv.LV_PALETTE_PINK lv.LV_PALETTE_PURPLE lv.LV_PALETTE_DEEP_PURPLE lv.LV_PALETTE_INDIGO lv.LV_PALETTE_BLUE lv.LV_PALETTE_LIGHT_BLUE lv.LV_PALETTE_CYAN lv.LV_PALETTE_TEAL lv.LV_PALETTE_GREEN lv.LV_PALETTE_LIGHT_GREEN lv.LV_PALETTE_LIME lv.LV_PALETTE_YELLOW lv.LV_PALETTE_AMBER lv.LV_PALETTE_ORANGE lv.LV_PALETTE_DEEP_ORANGE lv.LV_PALETTE_BROWN lv.LV_PALETTE_BLUE_GREY lv.LV_PALETTE_GREY
این راهنمای کامل تمام ویجتهای اصلی LVGL را همراه با مدیریت حافظه پیشرفته پوشش میدهد و بهترین روشها برای ایجاد رابطهای کاربری پایدار و بدون memory leak را ارائه میکند.
📦 لینکهای مرجع و منابع
🔗 مخزن گیتهاب ESP32 EVM:
https://github.com/hadipic/evm-linux?tab=readme-ov-file
https://github.com/hadipic/esp32-evm-bin?tab=readme-ov-file
🔗 کانال تلگرام EVM:
https://t.me/esp32_evm
