LVGL庫入門教程04-樣式

来源:https://www.cnblogs.com/frozencandles/archive/2022/06/18/16387933.html
-Advertisement-
Play Games

1、Linux常用命令 1.1、Linux命令初體驗 在日常使用過程當中經常使用到的命令有如下幾種 命令 對應英文 作用 ls [目錄名] list 查看當前目錄下的內容 pwd print work directory 查看當前所在目錄 cd [目錄名] change directory 切換目錄 ...


LVGL樣式

LVGL樣式概述

創建樣式

在 LVGL 中,樣式都是以對象的方式存在,一個對象可以描述一種樣式。每個控制項都可以獨立添加樣式,創建的樣式之間互不影響。

可以使用 lv_style_t 類型創建一個樣式並初始化:

static lv_style_t style;
lv_style_init(&style);

樣式是延遲渲染的,因此需要使用 static 存儲類別說明符或將其聲明為全局變數。

樣式是多方面的,不僅包括顏色和形狀,還包括邊距、邊框,甚至動畫變換效果等細節。

LVGL 中的樣式從 CSS 中吸取了很多靈感,因此對樣式的操作都類似 CSS

接下來,可以對得到的樣式對象設置一些樣式規則:

/* ... create and init style ... */
lv_style_set_radius(&style_btn_safe, 15);
lv_style_set_bg_opa(&style_btn_safe, LV_OPA_COVER);
lv_style_set_bg_color(&style_btn_safe, lv_palette_main(LV_PALETTE_GREEN));
lv_style_set_border_width(&style_btn_safe, 5);

所有的設置樣式函數都是 lv_style_set_...() 形式,完整的樣式規則將在之後介紹。未指定的樣式規則將保持控制項的預設樣式。

然後就可以將樣式分配給控制項,例如,以下創建了一個按鈕並利用 lv_obj_add_style() 函數設置其樣式為剛纔創建的樣式了:

lv_obj_t* btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 120, 50);
lv_obj_t* label = lv_label_create(btn);
lv_label_set_text(label, "Button");
lv_obj_add_style(btn, &style_btn_safe, 0);

這樣按鈕的外觀就會被改變了,效果為:

以上修改了按鈕的顏色,如果對顏色的創建過程不太理解也不要緊,以後會介紹顏色的代碼描述。可以簡單地將 GREEN 改成其它顏色名來改變不同的顏色。設置樣式的函數最後有一個參數 0 ,它代表的是樣式的選擇器,將會在接下來介紹。

一個文件內可以創建多種不同的樣式對象,這樣同一個界面中按鈕可以表現出多種不同的樣式。

樣式的級聯

所謂“級聯”(cascading),指的是將多個樣式分配給一個對象。此時如果多個樣式間設置的樣式屬性有重覆,那麼將使用最後設置的樣式值。也就是說,後設置的樣式具有更高的優先順序。

控制項在創建時可以視為同時添加了一個預設的樣式,因此在代碼中指定的任意樣式都會覆蓋預設的樣式。

還有一種特殊的局部樣式(local styles),局部樣式具有最高的優先順序,但只對單個控制項有效。局部樣式的創建類似如下:

lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_RED), 0);

它們都是 lv_obj_set_style_...() 形式的函數。

局部樣式一旦被設置,只能再次通過局部樣式修改回來。因此,局部樣式需要謹慎使用。

選擇器

LVGL 的選擇器(selector)與 CSS 不同。在 CSS 中,樣式通過選擇器選擇需要作用的元素;而 LVGL 中,樣式通過選擇器作用於控制項的部分。

要明白什麼是控制項的部分,需要分析控制項的組成。例如,以下代碼可以創建一個滑塊(slider)控制項:

lv_obj_t* slider01 = lv_slider_create(lv_scr_act());

滑塊是一種調整類型的控制項,用戶可以通過拖動它的把手(knob)來調節滑塊當前的數值。滑塊預設的表現形式為:

仔細觀察滑塊的組成,滑塊可以由主體外形、把手(knob)和進度指示條(indicator)組成。可以通過選擇器單獨設置這三個構成部分的樣式。例如,假設需要更改這三個部分的樣式,就可以通過選擇器分別指定修改的結構:

static lv_style_t style_slider_main;
lv_style_init(&style_slider_main);
lv_style_set_bg_opa(&style_slider_main, LV_OPA_COVER);
lv_style_set_bg_color(&style_slider_main, lv_palette_main(LV_PALETTE_YELLOW));
/* using selectors */
lv_obj_add_style(slider01, &style_slider_main, LV_PART_MAIN);
lv_obj_set_style_radius(slider01, 0, LV_PART_KNOB);
lv_obj_set_style_bg_color(slider01, lv_palette_main(LV_PALETTE_RED), LV_PART_INDICATOR);

這裡分別使用全局樣式和局部樣式修改控制項的各個部分。修改之後,把手部分變成了方形,主體和進度進度的顏色都發生了變化:

選擇器的一個更妙的用途是和控制項狀態做按位或運算,從而可以修改某個部分在某個狀態下的樣式。例如,選擇器

lv_obj_add_style(slider01, &style_slider_main, 
                 LV_PART_MAIN | LV_STATE_PRESSED);

使滑塊的主體只有在按下時才會使用該樣式(顏色被改變):

image

LVGL 的選擇器在表現形式上效果非常像 CSS 的偽元素和偽類選擇器。

滑塊在拖動過程中,會不斷觸發 LV_EVENT_VALUE_CHANGED 事件,可以使用函數

static inline int32_t lv_slider_get_value(const lv_obj_t* obj);

獲取當前獲取的滑塊數值(介於 0~100 )。更多的滑塊 API 可以參考官方文檔的介紹。

接下來詳細地介紹樣式可以設置的一些屬性。

樣式屬性

尺寸和位置

要理解尺寸和位置是如何起作用的,首先要理解 LVGL 的盒子模型。官方文檔給出了一張圖,可以很好地描述一個控制項的框架結構:

在設置尺寸的時候,長和寬指的是包括邊框(border)厚度的長寬,也就是不包括輪廓(outline)的總長寬。

在設置位置的時候,設置的坐標指的是 border 左上角相對父容器的 Content area 的坐標,也就是說如果設置坐標為 0 的話,輪廓(outline)可能會被父容器的邊框(border)遮蓋。

下表總結了尺寸與位置有關的可用屬性有:

屬性 描述 預設值
width 寬度 由控制項類別決定
min_width 最小寬度 0
max_width 最大寬度 屏幕的寬度
height 高度 由控制項類別決定
min_height 最小寬度 0
max_height 最大寬度 屏幕的高度
align 對齊方式 左上方
x 對齊後在水平方向的偏移量 0
y 對齊後在豎直方向的偏移量 0

註意這裡有一個最小或最大的寬度和高度,在上一節介紹 flex 和 grid 佈局時就展示過控制項寬度隨佈局自動調整的情況,因此可以給它們提供一個閾值防止過大或過小。

不過上一節還有一個地方沒有提到:在設置寬度和高度時,除了使用確定的數值外,還可以使用百分比值 lv_pct(x) 來設置控制項相對父容器的 Content area 的大小或位置。例如,樣式

lv_style_set_width(&style, lv_pct(25));
lv_style_set_x(&style, lv_pct(50));

可以讓一個控制項的水平尺寸占據父容器的 1/2~3/4 的位置:

對於父容器而言,還可以使用 LV_SIZE_CONTENT 特殊單位調整其尺寸至可以容納所有包含控制項的合適值。例如,按鈕就是一個這樣的容器,它的預設樣式就通過該值使得其寬度和高度可以自動適應包含的標簽尺寸。

邊框和邊距

上圖展示的文本框就有一個深灰色的邊框。邊框就無需額外描述了,與邊框有關的樣式屬性有:

屬性 描述 預設值
border_width 邊框寬度,只能用絕對寬度描述 0
border_side 繪製哪些部分的邊框 LV_SIDE_ALL
border_post 繪製順序,設置 true 表示包含的子控制項繪製完成了再繪製邊框 false
... 與顏色有關的屬性將在之後介紹

邊框和主體部分之間被邊距(padding)隔開。和邊距有關的樣式屬性有:

屬性 描述 預設值
pad_top 上邊距 0
pad_bottom 下邊距 0
pad_left 左邊距 0
pad_right 右邊距 0
pad_row 當控制項擁有佈局時,每行間的間距 0
pad_column 當控制項擁有佈局時,每列間的間距 0

不過在設置佈局時,還提供了幾個簡寫屬性:可以使用 ...pad_all() 一併設置上下左右的邊距;或使用 ...pad_hor()...pad_ver() 設置水平和垂直的邊距;還可以使用 ...pad_gap() 設置行和列的間距。

輪廓

輪廓(outline)類似邊框,但輪廓並不算在一個控制項的主體內,因此設置坐標、尺寸等屬性時都不包含輪廓的尺寸。

輪廓可設置的屬性遠比邊框少。下表列出了輪廓的一些屬性:

屬性 描述 預設值
outline_width 輪廓寬度 0
outline_pad 輪廓到主體的間距 0
... 與顏色有關的屬性將在之後介紹

輪廓和邊框最根本的差異是兩者不是同一個東西,因此可以在同一個元素同時使用不同樣式的輪廓的邊框來實現一些有趣的效果,例如:

lv_style_set_radius(&style, 0);
lv_style_set_border_color(&style, lv_palette_main(LV_PALETTE_GREY));
lv_style_set_border_width(&style, 5);
lv_style_set_border_opa(&style, LV_OPA_COVER);
lv_style_set_border_side(&style, LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_RIGHT);
lv_style_set_outline_width(&style, 4);
lv_style_set_outline_pad(&style, 1);
lv_style_set_outline_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 1));

表現效果為:

陰影

陰影可以使控制項看起來有立體感。下表列出了設置陰影的一些屬性:

屬性 描述 預設值
shadow_width 設置陰影的模糊半徑 0
shadow_ofs_x 設置陰影的水平偏移量 0
shadow_ofs_y 設置陰影的垂直偏移量 0
shadow_spread 設置陰影的放大量 0
... 與顏色有關的屬性將在之後介紹

例如,以下設置模糊半徑為 50 的藍色陰影:

lv_style_set_shadow_width(&style, 50);
lv_style_set_shadow_color(&style, lv_palette_main(LV_PALETTE_BLUE));

效果為:

以下設置放大有偏移的紅色陰影:

lv_style_shadow_color(&style, lv_palette_main(LV_PALETTE_RED))
lv_style_set_shadow_width(&style, 15)
lv_style_set_shadow_ofs_x(&style, 10)
lv_style_set_shadow_ofs_y(&style, 20)
lv_style_set_shadow_spread(&style, 10)

效果為:

LVGL 中無法給同一個控制項設置多個陰影疊加,從而實現更複雜的效果,這是比較可惜的一點。

文本樣式

在創建控制項時經常要使用文字,下表列出了能影響文字效果的一些屬性:

屬性 描述 預設值
text_font 設置文字的字體 預設字體
text_letter_space 字元間隔 0
text_line_space 設置多行文本的行間距 0
text_decor 設置文本裝飾(下劃線或刪除線) LV_TEXT_DECOR_NONE
text_align 設置文本對齊方式 LV_TEXT_ALIGN_AUTO
... 與顏色有關的屬性將在之後介紹

需要註意的是,文本的樣式是可繼承的,意思是如果子控制項沒有特別指定的話,它會使用父容器設置的文本樣式。

在一段文本內可能存在許多種樣式,對此,可以使用類似 CSS 的 span 來拆分樣式在文本內的作用域。為了創建 span ,首先需要創建一個 span-group :

lv_obj_t* spangroup = lv_spangroup_create(lv_scr_act());
lv_obj_set_size(spangroup, 160, LV_SIZE_CONTENT);

創建的 span-group 和一般的控制項沒什麼區別,可以給它添加一些樣式:

lv_obj_set_style_border_color(spangroup, lv_palette_main(LV_PALETTE_BLUE), 0);
lv_obj_set_style_border_width(spangroup, 1, 0);
lv_obj_set_style_pad_all(spangroup, 5, 0);

span-group 提供的以下函數使得它相比標簽更適合用來處理大段的文本:

函數 介紹
lv_spangroup_set_align(obj, align) 設置文本的對齊
lv_spangroup_set_overflow(obj, overflow) 控制溢出文本的處理方式
lv_spangroup_set_indent(obj, indent) 設置文本的首行縮進,單位為像素
lv_spangroup_set_mode(obj, mode) 設置對多行文本的折行處理,可以參見枚舉 lv_span_mode_t

有了 span-group 以後,可以使用以下代碼從中創建一個 span 並設置文本:

lv_span_t* span = lv_spangroup_new_span(spangroup);
lv_span_set_text(span, "LVGL is an open-source graphics library");

每一個 span 都提供了一個獨立的樣式介面,可以單獨設置範圍內文本的樣式:

lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_BLUE));

一個 span-group 可以創建多個 span ,並且它們的樣式效果互不影響:

span = lv_spangroup_new_span(spangroup);
lv_span_set_text(span, "providing everything");
lv_style_set_text_decor(&span->style, LV_TEXT_DECOR_UNDERLINE);
lv_style_set_text_font(&span->style, &lv_font_montserrat_20);
/* ... */
span = lv_spangroup_new_span(spangroup);
lv_span_set_text(span, "to create embedded GUI");

效果為:

可以註意到預設的 span-group 是沒什麼樣式的。span-group 還有很多的 API ,具體可以參照官方文檔的相關介紹。

其它樣式

下表列出了一些其它的樣式屬性:

屬性 描述 預設值
radius 設置控制項的圓角,該屬性會一併影響邊框和輪廓 0,即無圓角
clip_corner 如果有圓角,是否要將 Content-aera 超出圓角的部分去除
layout 設置控制項的佈局方式 0
base_dir 設置文字的書寫方向,它會同時影響佈局的方向 預設書寫方向
... 與顏色有關的屬性將在之後介紹

在設置半徑時可以使用百分數,例如 lv_pct(50) 將使控制項變成圓形。

以上列出了大部分的樣式屬性,但是除了顏色外還有許多樣式沒有介紹,例如變換、動畫、漸變等,這些留到之後介紹。LVGL 中還存在一些特殊的樣式,它們是為相應的控制項設計的,接下來介紹這些控制項及樣式。

基本圖形:直線和弧線

直線

LVGL 中的直線(line)實際上指的是折線,因為它可以一次性連續繪製多條相接的線段。為了繪製折線,首先要準備一些端點的坐標:

static lv_point_t line_points[] = { {217, 36}, {35, 49}, {281, 163}, {110, 162}, {257, 111} };

然後可以通過這些端點來創建折線:

lv_obj_t* line1 = lv_line_create(lv_scr_act());
lv_line_set_points(line1, line_points, 5);

效果為:

創建的折線作為一個整體,實際上也是一個控制項,當然可以給它加上各種屬性:

static lv_style_t style_line;
lv_style_init(&style_line);
lv_style_set_align(&style_line, LV_ALIGN_TOP_MID);
lv_style_set_border_width(&style_line, 4);
lv_obj_add_style(line01, &style_line, 0);

效果為:

折線擁有一些特殊的樣式屬性,是其它控制項所沒有的。下表列出了折線的特殊屬性:

屬性 描述 預設值
line_width 設置線段寬度 0
line_dash_width 設置虛線實部分的距離 0
line_dash_gap 設置虛線虛部分的距離 0
line_rounded 設置線段端點是否為圓角
line_color 設置線段顏色 黑色
line_opa 設置顏色透明度 不透明

註意,虛線只對水平和垂直的線段有效,並且只有兩個屬性都不為 0 才有虛線的效果。

例如,樣式:

lv_style_set_line_color(&style_line, lv_palette_main(LV_PALETTE_BLUE));
lv_style_set_line_width(&style_line, 8);

表現效果為:

如果再添加上:

lv_style_set_line_dash_width(&style_line, 10)
lv_style_set_line_dash_gap(&style_line, 5)
lv_style_set_line_rounded(&style_line, true);

那麼效果就變成:

關於折線還有一個函數 lv_line_set_y_invert(lv_obj_t *obj, bool en) 可以用來控制繪製的折線垂直翻轉(即翻轉 y 軸)。除此之外折線並沒有什麼可以介紹的。在後續還會介紹圖表,可以繪製更美觀的折線效果。

圓弧

LVGL 中的圓弧(arc)儘管和直線同屬於基礎控制項,但圓弧的功能遠比直線豐富,甚至 API 比起滑塊這些複雜的控制項都多。

首先簡單創建一個圓弧,查看它的預設效果:

lv_obj_t* arc01 = lv_arc_create(lv_scr_act());

預設的效果為:

可以看出圓弧的在預設情況下,它的表現形式實際上就是弧形的滑塊。如果想要得到純粹的圓弧,可以將圓弧的把手刪除:

lv_obj_remove_style(arc01, NULL, LV_PART_KNOB);
lv_obj_clear_flag(arc01, LV_OBJ_FLAG_CLICKABLE);

這裡做了兩件事:首先是將把手的樣式刪除,這裡第二個參數 NULL 表示刪去全部樣式;其次將圓弧的可點擊標誌位清除,使它不再能接收用戶的點擊事件。這樣圓弧看起來就純粹多了:

還可以進一步刪去圓弧的指示條(indicator),讓它更像傳統的圓弧。

預設的圓弧是開口向下的 270° 圓弧。為了設置圓弧的形狀,可以使用函數

void lv_arc_set_angles(lv_obj_t *obj, uint16_t start, uint16_t end);
void lv_arc_set_bg_angles(lv_obj_t *obj, uint16_t start, uint16_t end);

分別修改前景和背景的圓弧起止範圍,單位為角度。註意,圓弧的角度 0° 是正右方向,90° 是正下方向,以此類推。這兩個函數都有單獨設置起或止位置的版本。例如,設置

lv_arc_set_bg_angles(arc01, 0, 270);
lv_arc_set_end_angle(arc01, 180);

可以將圓弧的角度調整為:

圓弧也像直線一樣具有特殊的樣式,下表列出了圓弧具有的樣式屬性:

屬性 描述 預設值
arc_width 設置圓弧寬度 0
arc_rounded 設置圓弧端點是否為圓角
arc_color 設置圓弧顏色 黑色
arc_opa 設置圓弧透明度 不透明
arc_img_src 設置圓弧填充圖片 無填充圖片

以上是官方文檔的介紹,但這個預設值顯然與實際不符。之所以會這樣,原因是在 lv_conf.h 大約 514 行,啟用過預設的樣式:

/*A simple, impressive and very complete theme*/
#define LV_USE_THEME_DEFAULT 1

而該樣式在初始化時,就會修改包括圓弧在內的一些樣式,因此圓弧、按鈕等控制項才預設表現為這個模樣。

圓弧可以作為一個基準讓控制項對齊。例如,可以使用

lv_arc_rotate_obj_to_angle(arc01, label, 25);

讓一個標簽旋轉對齊圓弧的把手,第三個參數為半徑的偏移量,效果為:

與其說是對齊把手,更準確的說法是對齊圓弧當前的值。例如,可以通過以下函數改變圓弧的值:

lv_arc_set_value(arc01, 20);

這樣效果就很明顯了:

圓弧預設的取值範圍是 0~100 ,也可以通過 lv_arc_set_range(obj, min, max) 函數修改這一取值範圍。除此之外,還有另一個函數 lv_arc_align_obj_to_angle(obj, obj_to_align, r_offset) 只對齊控制項而不發生旋轉。另外需要註意,應該先對齊圓弧後,再設置標簽的對齊,否則標簽會因為不是包含關係而不隨之更新位置。

總體來說,圓弧因為不是純粹的圓弧,因此它具有滑塊的各種特征,例如可以響應 LV_EVENT_VALUE_CHANGED 事件,可以使用 lv_arc_get_value(obj) 獲取值等。

首發於:http://frozencandles.fun/archives/361

參考資料/延伸閱讀

https://docs.lvgl.io/master/overview/style.html

官方文檔——樣式簡介

https://docs.lvgl.io/master/overview/style-props.html

官方文檔——所有的樣式屬性簡介


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近在看 C++ 的方法和類模板,我就在想 C# 中也是有這個概念的,不過叫法不一樣,人家叫模板,我們叫泛型,哈哈,有點意思,這一篇我們來聊聊它們底層是怎麼玩的? 一:C++ 中的模板玩法 畢竟 C++ 是相容 C 語言,而 C 是過程式的玩法,所以 C++ 就出現了兩種模板類型,分別為:函數模板 ...
  • 一、CDN是什麼? CDN的全稱是Content Delivery Network,即內容分髮網絡。其目的是通過在現有的Internet中增加一層新的CACHE(緩存)層,將網站的內容發佈到最接近用戶的網路”邊緣“的節點,使用戶可以就近取得所需的內容(就近原則),提高用戶訪問網站的響應速度。從技術上 ...
  • Air105 有 1 個 Timer 單元,包含 8 個獨立定時器: Timer0 到 Time7, 8 個定時器中斷源獨立,每個定時器單獨占 1 個中斷源, 使用 PCLK 時鐘頻率作為定時器計時鐘源, 定時器採用向下計數方式. 每個 Timer 單元定時器都支持 PWM 模式, PWM 模式最高... ...
  • #一、防火牆配置 前言:電腦的防火牆配置保證了別的主機無法訪問本機非開放埠 1、防火牆介紹 Linux預設防火牆是開啟的,而且所以的埠對外都是不可訪問的,該策略保證了電腦的安全 但同時也帶來了問題如:其他電腦無法訪問本機上項目開啟的埠號 在Linux上安裝Tomcat,Tomcat軟體需 ...
  • 一、功能變數名稱系統概述 功能變數名稱系統DNS(Domain Name System)是網際網路使用的命名系統,用來把便於人們使用的機器名字轉換成為IP地址。功能變數名稱系統其實就是名字系統。為什麼不叫“名字”而叫“功能變數名稱”呢?這是因為在這種網際網路的命名系統中使用了許多的“域(domain)”,因此就出現了“功能變數名稱”這個名詞。 ...
  • vmstat 是一個查看虛擬記憶體(Virtual Memory)使用狀況的工具,但是怎樣通過 vmstat 來發現系統中的瓶頸呢? 1。 使用vmstat 使用前我們先看下命令介紹及參數定義 Usage: vmstat [options] [delay [count]] Options: -a, - ...
  • Air105 的時鐘 高頻振蕩源 * 晶元支持使用內部振蕩源, 或使用外置12MHz晶體 * 晶元上電覆位後 ROM boot 啟動過程基於內部12MHz的振蕩器 * 晶元內部集成的12MHz振蕩源精度為±2%, 精度一般 * 使用外置12MHz晶體, 需要軟體切換 * 經過PLL倍頻後為系統提供... ...
  • 寫在前面 前些天看了一本漫畫,裡面一個老技術人員的話,讓我不自覺的想到很多東西。 是啊,有時候我們自認為的自我實現,其實就是在湊這個時代的熱鬧,每個時代都有自己的熱鬧,個人之於時代不過是浪花一朵朵。 但這並不能作為我們不去湊這個熱鬧的理由,你去湊時代的這個熱鬧,這個時代必會給予你獎勵,或早或晚,或大 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...