[LVGL] 布局系統 lv_flex, lv_grid | 輸入設備 lv_indev | union

第五章:布局系統(lv_flex, lv_grid)

歡迎回來!

在第四章:樣式(lv_style)中,我們掌握了如何通過色彩、字體和圓角等特性美化部件。當界面元素具備視覺吸引力后,如何優雅地組織它們便成為新的挑戰。

設想我們擁有多個精美按鈕,希望實現以下布局效果:

  • 橫向/縱向等距排列
  • 屏幕尺寸變化時自動適配
  • 動態增刪元素時自動調整

傳統手工計算坐標的方式顯然低效且難以維護,這正是布局系統的價值所在。

布局系統核心價值

LVGL布局系統受現代網頁設計(CSS Flexbox/Grid)啟發,通過聲明式配置實現:

在這里插入圖片描述

布局類型概覽

布局類型適用場景典型應用
彈性布局單向流式排列導航欄|設置項列表
網格布局二維矩陣排列儀表盤|相冊縮略圖

啟用布局模塊

lv_conf.h中激活配置:

/*==================* 布局模塊*================*/
#define LV_USE_FLEX 1  // 啟用彈性布局
#define LV_USE_GRID 1  // 啟用網格布局

彈性布局(lv_flex)

1. 容器初始化

lv_obj_t * flex_container = lv_obj_create(screen_main);
lv_obj_set_size(flex_container, LV_PCT(90), LV_PCT(80)); // 相對父容器90%寬/80%高
lv_obj_set_layout(flex_container, LV_LAYOUT_FLEX);       // 聲明彈性容器

2. 排列方向控制

// 橫向排列(可換行)
lv_obj_set_flex_flow(flex_container, LV_FLEX_FLOW_ROW_WRAP);// 縱向排列(可換列)
lv_obj_set_flex_flow(flex_container, LV_FLEX_FLOW_COLUMN_WRAP);

3. 對齊方式

// 主軸居中|交叉軸居中|軌道居中
lv_obj_set_flex_align(flex_container, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);

4. 空間分配

lv_obj_t * expand_btn = lv_button_create(flex_container);
lv_obj_set_flex_grow(expand_btn, 2);  // 占據剩余空間2份lv_obj_t * normal_btn = lv_button_create(flex_container);
lv_obj_set_flex_grow(normal_btn, 1);  // 占據剩余空間1份

5. 間距控制

static lv_style_t flex_style;
lv_style_init(&flex_style);
lv_style_set_pad_column(&flex_style, 10);  // 列間距10像素
lv_style_set_pad_row(&flex_style, 15);     // 行間距15像素
lv_obj_add_style(flex_container, &flex_style, 0);

網格布局(lv_grid)

1. 容器初始化

lv_obj_t * grid_container = lv_obj_create(screen_main);
lv_obj_set_layout(grid_container, LV_LAYOUT_GRID);  // 聲明網格容器

2. 網格結構定義

// 列定義:固定100px|彈性1份|彈性2份
static int32_t col_dsc[] = {100, LV_GRID_FR(1), LV_GRID_FR(2), LV_GRID_TEMPLATE_LAST};// 行定義:自適應內容高度|彈性3份
static int32_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_FR(3), LV_GRID_TEMPLATE_LAST};lv_obj_set_grid_dsc_array(grid_container, col_dsc, row_dsc);

3. 單元格定位

// 按鈕定位到(0,0)單元格,橫向居左|縱向居頂
lv_obj_t * btn = lv_button_create(grid_container);
lv_obj_set_grid_cell(btn, LV_GRID_ALIGN_START, 0, 1,   // 列:起始對齊,第0列,跨1列LV_GRID_ALIGN_START, 0, 1);  // 行:起始對齊,第0行,跨1行// 標簽跨兩列
lv_obj_t * label = lv_label_create(grid_container);
lv_obj_set_grid_cell(label,LV_GRID_ALIGN_CENTER, 1, 2,  // 列:居中,第1列,跨2列LV_GRID_ALIGN_CENTER, 0, 1); // 行:居中,第0行,跨1行

布局系統工作原理

處理流程

在這里插入圖片描述

核心機制

  1. 注冊機制通過lv_obj_set_layout()將容器注冊到布局系統
  2. 延遲計算:在屏幕刷新周期統一處理布局計算
  3. 動態響應:容器尺寸變化或子元素增減時自動觸發重新布局

實踐

  1. 組合使用:在復雜界面中混合使用FlexGrid布局
  2. 響應式設計:結合LV_PCT百分比單位和媒體查詢實現自適應
  3. 性能優化避免深層嵌套布局,控制刷新頻率
  4. 樣式分離:將布局樣式與視覺樣式分離管理

結論

通過本章學習,我們掌握了:

  • 彈性布局的流式排列空間分配技巧
  • 網格布局的二維矩陣定位方法
  • 布局系統的底層運作原理
  • 間距控制與對齊策略

布局系統的引入使界面開發從手工計算邁向聲明式配置,極大提升了開發效率和可維護性。

下一章我們將探索用戶交互的核心——輸入設備管理

下一章:輸入設備(lv_indev)


github: https://github.com/lvy010/Cpp-Lib-test/tree/main/LVGL/indev

第六章:輸入設備(lv_indev)

在第五章:布局(lv_flex, lv_grid)中,我們已成為屏幕布局的大師,能夠確保界面元素美觀且自適應。但若用戶無法真正觸摸交互這些精心設計的界面,再驚艷的UI又有何用?

如何才能讓那個完美居中、藍色圓角按鈕真正被點擊?

這正是**輸入設備(lv_indev)**大顯身手之時~

假設我們的設備擁有物理觸摸屏、鼠標、鍵盤甚至旋轉編碼器,LVGL需要通過某種方式理解用戶通過這些物理輸入設備的操作,并將這些動作轉化為屏幕上控件(如按鈕、滑塊或文本輸入框)能夠理解和響應的指令

lv_indev模塊就像用戶交互的通用翻譯器。

它接收來自硬件的原始信息(例如"手指觸摸了X,Y坐標"或"Enter鍵被按下"),并將其轉化為GUI可理解的語義事件。

這使得LVGL應用能夠響應多樣化的物理輸入,而無需為每個交互編寫復雜的硬件專用代碼。

本章目標是理解如何連接常見輸入設備——觸摸屏(屬于"指針"類設備),讓LVGL按鈕能夠響應點擊操作

什么是lv_indev

lv_indev(LVGL輸入設備縮寫,代碼中以lv_indev_t結構體表示)是表征單個輸入硬件設備的對象。

它充當微控制器原始輸入數據與LVGL事件系統之間的橋梁。

lv_indev_t對象管理的關鍵要素:

  • 設備類型:屬于觸摸屏、鍵盤還是編碼器?
  • 數據讀取:需要開發者提供的特殊函數(“讀取回調”)來獲取硬件當前狀態
  • 當前狀態:按壓/釋放狀態、指向位置或激活的按鍵
  • 關聯顯示:該輸入設備控制的顯示設備(回憶第二章:顯示設備(lv_display))

輸入設備類型(LV_INDEV_TYPE_

LVGL支持多種輸入設備類別:

類型描述典型硬件
LV_INDEV_TYPE_POINTER能夠指向屏幕具體坐標并觸發按壓/釋放動作的設備觸摸屏、鼠標、軌跡球
LV_INDEV_TYPE_KEYPAD提供按鍵輸入的設備,常用于導航和文本輸入物理鍵盤、數字鍵盤
LV_INDEV_TYPE_ENCODER帶有增量旋轉(左/右)和可選按壓按鈕的旋轉設備旋鈕編碼器、滾輪
LV_INDEV_TYPE_BUTTON映射到屏幕坐標的物理按鍵(如設備外殼上的實體按鈕) 前面板按鍵

本章將以LV_INDEV_TYPE_POINTER類型的觸摸屏為例進行說明。

連接第一個輸入設備(觸摸屏)

讓我們配置基礎觸摸屏功能,使LVGL能夠檢測按鈕的觸摸操作。

1. 創建輸入設備對象

首先需要通過創建lv_indev_t對象告知LVGL存在輸入設備。

該操作必須在顯示設備(lv_display)創建之后執行。

#include "lvgl.h" // 始終包含主LVGL頭文件// 在應用初始化函數中(如main.c或app_init())
void setup_input_device() 
{// 確保顯示設備已初始化(例如調用第二章的setup_display())// lv_init();// setup_display(); // 需在輸入設備設置前調用!// 1. 創建輸入設備對象lv_indev_t * my_touchpad_indev = lv_indev_create();// ... 后續配置步驟在此添加
}
  • lv_indev_create():創建lv_indev_t對象,默認關聯到首個創建的顯示設備
  • lv_indev_t * my_touchpad_indev:該變量持有輸入設備的操作句柄

2. 設置設備類型

告知LVGL輸入設備類型,觸摸屏屬于LV_INDEV_TYPE_POINTER

// ...(接續前文代碼)void setup_input_device() 
{lv_indev_t * my_touchpad_indev = lv_indev_create();// 2. 設置輸入設備類型為POINTERlv_indev_set_type(my_touchpad_indev, LV_INDEV_TYPE_POINTER);// ... 后續配置步驟在此添加
}

3. 實現讀取回調函數

這是最關鍵的部分!LVGL需要通過開發者提供的"讀取回調"函數定期獲取實際觸摸數據。

my_touchpad_read函數需要完成:

  • 讀取觸摸的當前狀態(按壓或釋放)
  • 若處于按壓狀態,讀取X/Y坐標
  • 填充lv_indev_data_t結構體傳遞這些信息
// 將觸摸數據存儲為全局變量以便硬件驅動更新
//(例如在中斷服務例程或主循環輪詢中更新)
static int32_t touch_x = 0;
static int32_t touch_y = 0;
static bool touch_pressed = false; // 觸摸屏激活時為true// *** 重要:需替換為實際硬件讀取函數!***
// 以下僅為演示概念占位符
// 實際嵌入式系統中應讀取觸摸控制器IC數據
// 示例:*x = get_actual_touch_x(); *y = get_actual_touch_y(); *is_pressed = is_touch_down();void read_touchscreen_hardware(int32_t *x, int32_t *y, bool *is_pressed) 
{// 演示用模擬輸入(如PC模擬器中的鼠標)// 實際應用中應從觸摸傳感器獲取真實數據:*x = touch_x;*y = touch_y;*is_pressed = touch_pressed;
}// ****************************************************************************// 3. 自定義讀取回調函數
void my_touchpad_read(lv_indev_t * indev, lv_indev_data_t * data) {// 從實際觸摸硬件讀取當前狀態read_touchscreen_hardware(&touch_x, &touch_y, &touch_pressed);if (touch_pressed) {data->state = LV_INDEV_STATE_PRESSED; // 告知LVGL按壓狀態data->point.x = touch_x;              // 設置X坐標data->point.y = touch_y;              // 設置Y坐標} else {data->state = LV_INDEV_STATE_RELEASED; // 告知LVGL釋放狀態}
}
  • lv_indev_t * indev:觸發回調的輸入設備對象指針
  • lv_indev_data_t * data:必須填充當前輸入數據的結構體
  • LV_INDEV_STATE_PRESSED / LV_INDEV_STATE_RELEASED:指針設備的兩種基本狀態
  • data->point.x, data->point.y:按壓狀態時的坐標位置

4. 連接讀取回調

最后將my_touchpad_read函數關聯至輸入設備對象。

// ...(接續前文代碼)void setup_input_device() 
{lv_indev_t * my_touchpad_indev = lv_indev_create();lv_indev_set_type(my_touchpad_indev, LV_INDEV_TYPE_POINTER);// 4. 關聯讀取回調函數lv_indev_set_read_cb(my_touchpad_indev, my_touchpad_read);
}

現在調用setup_input_device()后,LVGL將周期調用my_touchpad_read獲取觸摸狀態,并據此判斷控件(如第三章:控件(lv_obj)中的按鈕)是否被點擊

若結合第四章:樣式(lv_style)中的LV_STATE_PRESSED樣式,我們甚至能看到按鈕在觸摸時的顏色變化

理解控件組(適用于鍵盤/編碼器)

POINTER設備通過直接點擊屏幕坐標交互

KEYPADENCODER設備則通過"焦點"與控件交互。

想象用鍵盤導航網頁:按Tab鍵在按鈕間切換焦點,Enter鍵點擊焦點按鈕。

LVGL使用**控件組(lv_group_t)**實現此機制。

  • 創建組lv_group_t * g = lv_group_create();
  • 添加控件至組lv_group_add_obj(g, my_button);(對所有需導航的交互控件執行此操作)
  • 為輸入設備分配組lv_indev_set_group(my_keypad_indev, g);

my_keypad_read回調報告LV_KEY_NEXT時,焦點將自動在g組的控件間切換

(Qt的話,有信號和槽機制)

[Qt] 信號和槽(1) | 本質 | 使用 | 自定義

[Qt] 信號和槽(2) | 多對多 | disconnect | 結合lambda | sum

輸入設備工作原理

讓我們觀察觸摸事件從硬件LVGL控件的傳遞過程。

  1. 輪詢/讀取:LVGL運行周期性定時器(由第一章:配置(lv_conf.h)中的LV_DEF_REFR_PERIOD控制,通常10-50ms)。該定時器觸發lv_indev_read_timer_cb,進而調用各注冊輸入設備的lv_indev_read
  2. 讀取回調lv_indev_read調用開發者實現的my_touchpad_read函數,從硬件讀取原始X/Y坐標和觸摸狀態
  3. 數據處理:將原始數據填入lv_indev_data_t結構體并返回
  4. 查找目標對象:LVGL獲取原始輸入數據后,對指針設備會基于X/Y坐標遍歷顯示設備上的所有活動控件(從頂層系統層到底層),查找位于觸摸點下的控件。此過程涉及坐標和可見性檢查
  5. 狀態與事件管理:確定目標控件后,LVGL更新其內部狀態(如LV_STATE_PRESSED)并觸發相關事件(如LV_EVENT_PRESSEDLV_EVENT_CLICKEDLV_EVENT_RELEASED)。若按壓狀態移動可能觸發滾動或拖拽

簡化序列圖如下:

在這里插入圖片描述

LVGL內部代碼解析:

調用lv_indev_create()時,LVGL會為lv_indev_t結構體分配內存。

該結構體保存指向讀取回調函數的指針、設備類型內部狀態變量關聯顯示設備指針

核心邏輯位于src/indev/lv_indev.c,以下是簡化代碼片段:

// 摘自lv_indev.c(簡化版)
lv_indev_t * lv_indev_create(void)
{// 為輸入設備對象分配內存lv_indev_t * indev = lv_ll_ins_head(indev_ll_head);// ... 初始化默認值 ...// 創建周期性調用讀取函數的定時器indev->read_timer = lv_timer_create(lv_indev_read_timer_cb, LV_DEF_REFR_PERIOD, indev);// ...return indev;
}void lv_indev_set_read_cb(lv_indev_t * indev, lv_indev_read_cb_t read_cb)
{// 存儲開發者提供的讀取回調函數指針indev->read_cb = read_cb;
}void lv_indev_read(lv_indev_t * indev)
{lv_indev_data_t data;// 調用開發者實現的讀取回調if(indev->read_cb) {indev->read_cb(indev, &data);}// ... 根據indev->type處理data ...if(indev->type == LV_INDEV_TYPE_POINTER) {indev_pointer_proc(indev, &data); // 處理指針數據}// ... 其他類型處理(鍵盤、編碼器、按鈕)...
}static void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data) 
{// ... 從data->point更新內部'act_point' ...// ... 通過pointer_search_obj()查找指針下對象 ...// ... 更新內部狀態(如i->pointer.act_obj, i->state)...if (i->state == LV_INDEV_STATE_PRESSED) {indev_proc_press(i); // 處理按壓邏輯} else {indev_proc_release(i); // 處理釋放邏輯}
}static void indev_proc_press(lv_indev_t * indev) 
{// ... 檢測新對象、長按、滾動的邏輯 ...// 若啟用,向活動對象(indev_obj_act)發送LV_EVENT_PRESSED事件// 示例:// lv_obj_send_event(indev_obj_act, LV_EVENT_PRESSED, indev_act);
}// lv_indev.h中完整的lv_indev_t定義
// 包含輸入設備狀態和配置的所有相關數據
typedef struct _lv_indev_t 
{// ... 其他成員 ...lv_indev_type_t type;            /**< 輸入設備類型(POINTER, KEYPAD, ENCODER, BUTTON) */lv_indev_read_cb_t read_cb;      /**< 輸入設備數據讀取函數 */lv_indev_state_t state;          /**< 當前狀態(PRESSED或RELEASED) */struct _lv_display_t * disp;     /**< 關聯的顯示設備 */lv_timer_t * read_timer;         /**< 周期性調用read_cb的定時器 */lv_group_t * group;              /**< 針對KEYPAD/ENCODER:交互的控件組 */// ... 指針、鍵盤等內部狀態變量 ...// 例如:lv_point_t pointer.act_point; 當前坐標// 例如:uint32_t keypad.last_key; 最后按下的鍵// ... 更多手勢、長按、滾動相關參數 ...
} lv_indev_t;

這種內部結構和處理流程確保了LVGL能夠高效處理多種輸入源,將底層硬件細節與GUI邏輯解耦。

代碼功能

lv_indev_create()函數是LVGL輸入設備系統的核心接口,用于創建并初始化一個輸入設備實例。

函數返回lv_indev_t結構體指針,該結構體存儲輸入設備的全部運行時數據。

內存分配與初始化

lv_ll_ins_head(indev_ll_head)通過鏈表管理器為輸入設備分配內存,同時將新設備插入全局鏈表頭部

返回的lv_indev_t指針包含以下關鍵字段:

  • read_timer:通過lv_timer_create()創建定時器,周期性地調用lv_indev_read_timer_cb觸發輸入事件處理
  • type:初始化為LV_INDEV_TYPE_NONE,需通過lv_indev_set_type()顯式設置
  • read_cb:初始化為NULL,需通過lv_indev_set_read_cb()綁定具體設備的讀取函數
回調機制實現

lv_indev_set_read_cb()將開發者實現的設備讀取函數指針存入indev->read_cb。當定時器觸發lv_indev_read()時,會通過該指針調用具體設備的讀取邏輯:

if(indev->read_cb) 
{indev->read_cb(indev, &data); // 回調開發者實現的硬件讀取接口
}
輸入數據處理流程
  1. 類型分發:根據indev->type進入對應處理器。以觸摸屏(LV_INDEV_TYPE_POINTER)為例:

    indev_pointer_proc(indev, &data); // 處理坐標數據
    
  2. 狀態機處理:在indev_pointer_proc()中:

    • 更新坐標act_point和當前活動對象act_obj
    • 根據state字段(PRESSED/RELEASED)分發給indev_proc_press()indev_proc_release()
  3. 事件生成:在按壓處理中通過lv_obj_send_event()發送標準事件:

    lv_obj_send_event(indev_obj_act, LV_EVENT_PRESSED, indev_act);
    
關鍵數據結構

lv_indev_t包含輸入設備的完整上下文:

typedef struct _lv_indev_t 
{lv_indev_type_t type;        // 設備類型標識lv_indev_read_cb_t read_cb;  // 設備級讀取回調lv_indev_state_t state;      // PRESSED/RELEASED狀態struct _lv_display_t * disp; // 綁定到特定顯示器lv_timer_t * read_timer;     // 輸入輪詢定時器union {lv_point_t act_point;   // 指針設備當前坐標uint32_t last_key;      // 鍵盤設備最后按鍵};// ...其他手勢/滾動參數...
} lv_indev_t;
?union

union 是一種特殊的 C 語言結構,允許同一塊內存存儲不同的數據類型(如 lv_point_tuint32_t),但同一時間只能使用其中一個成員,以節省內存空間

20.(C語言)聯合和枚舉全

code:

union {lv_point_t act_point;  // 用于存儲指針坐標(如觸摸屏位置)uint32_t last_key;     // 用于存儲鍵盤按鍵值
};
  • 共享內存act_pointlast_key 共用同一塊內存,修改其中一個會影響另一個的值
  • 應用場景:適合在設備只能觸發一種輸入(如觸摸或按鍵)時復用內存,減少資源占用。

調用

開發者需要實現三個基礎操作:

  1. 創建設備實例
  2. 設置設備類型
  3. 綁定讀取回調
lv_indev_t * touchpad = lv_indev_create();
lv_indev_set_type(touchpad, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(touchpad, my_touchpad_read);

總結

至此我們已成功為LVGL應用連接輸入設備!本章要點包括:

  • lv_indev是處理用戶輸入的核心模塊
  • LVGL支持多種輸入設備類型
  • 如何創建lv_indev_t對象、設置類型并提供硬件數據讀取回調
  • lv_indev如何將原始輸入轉化為控件交互
  • "控件組"對鍵盤和編碼器導航的重要性

配置完輸入設備后,我們精心設計的樣式化控件已具備完整交互能力!下一步將深入探索控件如何響應這些交互事件。

下一章:事件系統(lv_event)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94677.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94677.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94677.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux中的mkdir命令

基本語法mkdir 命令的基本語法如下&#xff1a;mkdir [選項] 目錄名創建單個目錄要創建一個新目錄&#xff0c;只需在 mkdir 后跟上目錄名稱。例如&#xff1a;mkdir new_folder這會在當前工作目錄下創建一個名為 new_folder 的目錄。創建多個目錄可以一次性創建多個目錄&#…

基于大數據的美食視頻播放數據可視化系統 Python+Django+Vue.js

本文項目編號 25003 &#xff0c;文末自助獲取源碼 \color{red}{25003&#xff0c;文末自助獲取源碼} 25003&#xff0c;文末自助獲取源碼 目錄 一、系統介紹二、系統錄屏三、啟動教程四、功能截圖五、文案資料5.1 選題背景5.2 國內外研究現狀 六、核心代碼6.1 查詢數據6.2 新…

微信小程序精品項目-基于springboot+Android的計算機精品課程學習系統(源碼+LW+部署文檔+全bao+遠程調試+代碼講解等)

博主介紹&#xff1a;??碼農一枚 &#xff0c;專注于大學生項目實戰開發、講解和畢業&#x1f6a2;文撰寫修改等。全棧領域優質創作者&#xff0c;博客之星、掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java、小程序技術領域和畢業項目實戰 ??技術范圍&#xff1a;&am…

(五)系統可靠性設計

2024年博主考軟考高級系統架構師沒通過&#xff0c;于是決定集中精力認真學習系統架構的每一個環節&#xff0c;并在2025年軟考中取得了不錯的成績&#xff0c;雖然做信息安全的考架構師很難&#xff0c;但找對方法&#xff0c;問題就不大&#xff01; 本文主要是博主在學習過程…

Shuffle SOAR使用學習經驗

Shuffle SOAR 1. 基礎操作與配置1.1 環境搭建與系統要求1.1.1 硬件與操作系統要求Shuffle SOAR 平臺作為一款開源的安全編排、自動化與響應&#xff08;SOAR&#xff09;工具&#xff0c;其部署方式靈活&#xff0c;支持云端和自托管兩種模式。對于自托管部署&#xff0c;官方推…

騰訊云 EdgeOne 產品分析與免費套餐體驗指南

本文圍繞騰訊云 EdgeOne 展開&#xff0c;全方位介紹它的核心能力、免費套餐內容&#xff0c;以及如何快速上手、監控和排查常見問題&#xff0c;幫助個人開發者和中小企業在不產生額外成本的前提下體驗高性能的邊緣加速與安全防護。 一、產品概述 EdgeOne 定位 一體化云服務平…

npm ERR! Unsupported URL Type “workspace:“: workspace:./lib

如下 npm install npm ERR! code EUNSUPPORTEDPROTOCOL npm ERR! Unsupported URL Type "workspace:": workspace:./libnpm ERR! A complete log of this run can be found in: D:\IDEA\nodejs\node_cache\_logs\2025-08-06T08_21_32_592Z-debug-0.log原因及解決 pac…

微積分: 變化與累積

微積分,這門研究變化與累積的數學分支,其核心思想竟與東方哲學中"易"的概念不謀而合。《易經》有云:“易有太極,是生兩儀”,而微積分正是通過"微分"與"積分"這對辯證統一的操作,揭示了世間萬物變化與永恒的奧秘。 #mermaid-svg-UjO6qqMm0h…

web-vue工作流程

接續bmcweb流程。 當登錄openbmc web頁面后,瀏覽器會根據index.html中的js文件中的routes信息,自動獲取信息,比如當前的網絡設置信息、Datetime時區時間信息等。 以獲取網絡配置信息為例: 瀏覽器從app.js獲取到settins->network的route:”/settings/network”,加載對應…

全球化2.0 | 泰國IT服務商攜手云軸科技ZStack重塑云租賃新生態

在全球數字化轉型不斷加速的今天&#xff0c;泰國企業對于高質量云服務的需求日益旺盛。作為深耕本地市場逾二十年的行業領先IT服務商&#xff0c;泰國IT服務商不僅覆蓋了IT系統、軟件、硬件及網絡等多個領域&#xff0c;還持續引領當地技術服務創新。近期&#xff0c;該泰國IT…

一文搞懂Hive臨時表操作秘籍

Hive 臨時表&#xff1a;數據處理的得力助手 在大數據處理的廣闊領域中&#xff0c;Hive 憑借其強大的數據倉庫功能&#xff0c;成為了眾多數據分析師和開發者的得力工具。Hive 提供了類似 SQL 的查詢語言 HiveQL&#xff0c;讓我們能夠方便地對存儲在 Hadoop 分布式文件系統&a…

瞬態吸收光譜儀的基本原理

目錄 1. 基態與激發態 2. 時間上的動力學信息 3. pump-probe探測技術 4. 時間延遲和同一光源 5. 延時線和OPA 6. 差分信號 7. 斬波器 原視頻鏈接&#xff1a;瞬態吸收光譜儀的基本原理_嗶哩嗶哩_bilibili 1. 基態與激發態 當光照射在物質上時&#xff0c;組成物質的微觀…

迭代器與生成器:Python 中的高效數據遍歷機制

一、迭代器和生成器的基本概念 1. 迭代器的定義和工作原理 &#xff08;1&#xff09;迭代器的概念 迭代器&#xff08;Iterator&#xff09; 是 Python 中一種支持逐個訪問元素的對象&#xff0c;它遵循 迭代器協議&#xff08;Iterator Protocol&#xff09;&#xff0c;即實…

Java 發送 HTTP POST請求教程

Java 發送 HTTP POST 請求的方法使用 HttpURLConnection&#xff08;原生 Java 支持&#xff09; 創建一個 HttpURLConnection 對象&#xff0c;設置請求方法為 POST&#xff0c;并寫入請求體數據。以下是一個簡單示例&#xff1a;import java.io.OutputStream; import java.ne…

計算機英語詳細總結

計算機英語作為信息技術領域的專用語言&#xff0c;融合了專業術語、縮寫、行業表達及技術文檔規范&#xff0c;是學習編程、從事 IT 工作的核心工具。以下從核心分類、應用場景、學習方法三方面詳細梳理&#xff1a;一、核心術語分類與高頻詞匯1. 編程語言與語法基礎基礎概念&…

「日拱一碼」045 機器學習-因果發現算法

目錄 基于約束的方法 (Constraint-based) 基于評分的方法 (Score-based) 基于函數因果模型的方法 (Functional Causal Models) 基于梯度的方法 (Gradient-based) 因果發現是機器學習中一個重要的研究方向&#xff0c;它旨在從觀測數據中推斷變量之間的因果關系 基于約束的…

S7-1200 串行通信介紹

S7-1200 串行通信S7-1200支持的串行通訊方式點對點&#xff08;PtP&#xff09;通信Modbus 主從通信USS 通信名稱CM 1241 RS232CM 1241 RS422/485CB 1241 RS485訂貨號6ES7241-1AH32-0XB06ES7241-1CH32-0XB06ES7241-1CH30-1XB0通訊口類型RS232RS422/RS485RS485波特率(bps)300 ;6…

達夢包含OR條件的SQL特定優化----INJECT-HINT優化方法

Time:2025/08/07Author:skatexg應用迭代發版須執行如下動作 1、按目標需求全面壓力測試&#xff0c;優化潛在慢SQL或設置特殊優化參數(如&#xff1a;OPTIMIZER_OR_NBEXP) 2、達夢數據庫有數據導入&#xff0c;必須收集統計信息達夢使用SF_INJECT_HINT系統函數對指定SQL增加HIN…

JSqlParser學習筆記 快速使用JSqlParser

文章目錄前言本章節源碼官方文檔信息認識JSqlParserHow it works? 它是如何工作的&#xff1f;知識點關于statement實際應用場景引入依賴Parser 解析SQL解析sql語句解析sql區分sql類型分析增刪改查語句查詢語句認識PlainSelect示范新增語句了解Insert常用方法示范更新語句刪除…

Godot ------ 中級人物血條制作01

Godot ------ 中級人物血條制作 引言 正文 傳統血條制作 方格血條制作 傳奇,暗黑破環神類血條顯示 引言 在此之前,我們分四篇介紹了 Godot 中人物血條的制作,但是我們用到的都是比較基礎的節點 ProgressBar,本文我們將介紹另外一種相對高級的節點 TextureProgressBar。 正…