lvgl修改輸入設備驅動使其支持鼠標右鍵、雙擊、滑輪...

? ? ? ? 我在前幾章移植 lvgl 到linux上時講過注冊鼠標驅動部分,那時候使用的時默認提供的驅動,支持的鼠標功能很少,只有左鍵點擊,那時候我提過我們可以修改驅動使其支持,下面是具體的實現。

????????

?? ? ? ??

????????看上面代碼,我們當時是直接用的默認的模板驅動,而下面則是我專門針對鼠標寫的一個驅動。這里的 evdev_fd 是輸入設備的文件描述符,也就是說lvgl默認提供一種設備,所以大家如果有多個輸入設備的話需要再準備幾個獨立的文件描述符以及驅動。這里官方提供的默認驅動是支持多種輸入設備的(比如鼠標,鍵盤,觸摸屏),所以看這代碼比較多。而我們在這里專門針對鼠標進行開發驅動,使其支持我們要的效果。
首先我們打開 lv_hal_indev.h 這個文件,我們需要加上一些額外的定義,如圖:

? ? ? ? 然后我們再打開lv_api_map.h,如下圖添加,遵循 lvgl 的風格

? ? ? ? 然后我們再 evdev.c 文件中添加鼠標驅動函數,位置大家可自行添加,我這里添加到 evdev_read 的下邊,代碼部分如下,不是很難,重點是理解輸入設備的一些參數意義,這里使用的 struct input_event 這個結構體,大部分鼠標都支持,如果你的鼠標是自定義的格式,那么需要自行看手冊進行轉化。

void mouse_event_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
{struct input_event in;while(read(evdev_fd, &in, sizeof(struct input_event)) > 0) {/* 發生鼠標移動,記錄其位置 */if(in.type == EV_REL) {if(in.code == REL_X) evdev_root_x += in.value;else if(in.code == REL_Y) evdev_root_y += in.value;else if(in.code == REL_WHEEL) data->enc_diff = in.value;    /* 將鼠標滑輪滾動轉化為LVGL的編碼器事件 */}/* 按鍵事件(包括鼠標) */else if(in.type == EV_KEY) {switch(in.code) {/* 左鍵 */case BTN_LEFT:if(in.value == 0)evdev_button = LV_INDEV_STATE_REL;else if(in.value == 1)evdev_button = LV_INDEV_STATE_PR;break;/* 右鍵 */case BTN_RIGHT:if(in.value == 0)evdev_button = LV_INDEV_STATE_RIGHT_REL;else if(in.value == 1)evdev_button = LV_INDEV_STATE_RIGHT_PR;break;/* 中鍵 */case BTN_MIDDLE:if(in.value == 0)evdev_button = LV_INDEV_STATE_MIDDLE_REL;else if(in.value == 1)evdev_button = LV_INDEV_STATE_MIDDLE_PR;break;default:break;}}/* 保存值 */data->point.x = evdev_root_x;data->point.y = evdev_root_y;data->state = evdev_button;/* 邊界檢測 */if(data->point.x < 0) data->point.x = 0;if(data->point.y < 0) data->point.y = 0;if(data->point.x > drv->disp->driver->hor_res) data->point.x = drv->disp->driver->hor_res;if(data->point.y > drv->disp->driver->ver_res) data->point.y = drv->disp->driver->ver_res;}
}

? ? ? ? 下面我們在修改一下sdl模擬器的驅動,我們再模擬器上進行測試,下面紅框是修改部分

? ? ? ? 接下來我們看一下 lv_indev.c 輸入設備核心代碼,下面的這個函數是輸入設備的核心函數,是 30ms 的定時函數,這個定時時間由 LV_INDEV_DEF_READ_PERIOD 這個宏決定的。而紅框部分則是對輸入設備的數據結構體的初始化值,最后調用我們上面寫的驅動函數將讀取的鼠標值轉化為 lvgl 數據結構體。

? ? ? ? 而在往下看則是對不同輸入設備的具體處理,我們重點關注紅框部分的鼠標處理函數

? ? ? ? 這個就是處理鼠標的處理函數,先是對坐標進行了處理,由于我們判斷過了這里就不再重復判斷了,而最下面的判斷是用于鼠標發生了移動重新繪制鼠標的位置的作用。

? ? ? ? 再往下面部分就是對事件的判斷從而返給對象,紅框部分是新增的使其支持我們自定義的功能。這里需要強調一下,indev_proc_press 這個函數是初次按下執行一系列操作,比如LV_EVENT_PRESSED (第一下按下時調用)、?LV_EVENT_PRESSING (還在按)、LV_EVENT_PRESS_LOST (目標丟失)、LV_EVENT_LONG_PRESSED(長按)、LV_EVENT_LONG_PRESSED_REPEAT(仍長按)這些重要的中間過,對于右鍵來說是大部分是不需要的,但是我們要保持完整性且目標丟失我們也需要,所以右鍵也去調用了這個函數

? ? ? ? 對 indev_proc_press 這個處理按下(一種過程,并非結束)的函數進行處理,重點展示修改的代碼,下面“時間”打錯字了,是事件

? ? ? ? 然后就是?indev_proc_release 這個函數,主要是 LV_EVENT_RELEASED(釋放)、LV_EVENT_SHORT_CLICKED(短按)、LV_EVENT_CLICKED(點擊)這些事件,這里右鍵是不需要的,所以加個判斷,同時要加上右鍵事件以及雙擊事件的發送,這里改動比較多,大家需注意:

? ? ? ? 到這里成功實現了雙擊、右鍵、以及鼠標滑輪功能,我們創建個box簡單測試一下

static void event_cb(lv_event_t *e)
{lv_event_code_t code = lv_event_get_code(e);if(code == LV_EVENT_CLICKED) printf("左鍵點擊事件\n");else if(code == LV_EVENT_RIGHT_CLICKED) printf("右鍵點擊事件\n");else if(code == LV_EVENT_DOUBLE_CLICKED) printf("左鍵雙擊事件\n");else if(code == LV_EVENT_MOUSE_WHEEL_UP) printf("鼠標滑輪上滑事件\n");else if(code == LV_EVENT_MOUSE_WHEEL_DOWN) printf("鼠標滑輪下滑事件\n");
}void page_create(void)
{lv_obj_t* box = lv_obj_create(lv_scr_act());lv_obj_set_size(box, 60, 60);lv_obj_add_event_cb(box, event_cb, LV_EVENT_ALL, NULL);
}

? ? ? ? 下面是輸出打印

? ? ? ? 到這里就完結了,其實 lvgl 的知識聽龐大的,需要大家慢慢挖索,我不建議大家一股腦的看源代碼,而是有需求用到了再去查看,探索是枯燥的,但是忍受下來你會發現其實就是那么簡單,我這里只是以三種事件為例子,其實還有鼠標懸停提示這種事件,其實也不難,需要大家好好摸索,最后謝謝大家的觀看。

?

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

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

相關文章

SpringBoot 中單獨一個類中運行main方法報錯:找不到或無法加載主類

1. 報錯SpringBoot項目&#xff0c;在隨機某個類使用main方法&#xff0c;點擊運行/調試報錯錯誤: 找不到或無法加載主類 com.central.workorder.config.PropertyEncrypt 原因: java.lang.ClassNotFoundException: com.central.workorder.config.PropertyEncrypt2. 原因縮短命令…

React 核心 Hook 與冷門技巧:useReducer、useEffect、useRef 及 is 屬性全解析

&#x1f4da; 前言React 的函數組件 Hooks 模式已經成為現代前端開發的主流。相比類組件&#xff0c;Hooks 讓狀態管理和副作用處理更加簡潔和可復用。但在實際開發中&#xff0c;除了常用的 useState 和 useEffect&#xff0c;還有很多“進階武器”值得我們掌握。本文將深入…

通義靈碼產品演示: 數據庫設計與數據分析

作者&#xff1a;了哥 演示主題&#xff1a;AI 進行數據庫設計以及做數據分析 演示目的 演示通義靈碼對于數據庫的設計能力以及數據分析能力。 演示準備 準備數據庫&#xff0c;這里為了簡單實用 sqlite3 brew install sqlite3使用 vscode&#xff0c;同時安裝好通義靈碼的插件…

MySQL主從同步參數調優案例

#作者&#xff1a;stackofumbrella 文章目錄一、前言二、故障概述2.1 基礎信息2.2 故障現象描述三、故障診斷分析3.1 排查過程3.2 問題根因四、故障解決方案 &#x1f4ca;4.1 解決方案 &#x1f6e0;?五、總結附件一、前言 在磐基系統中大量使用MySQL作為后端的數據存儲&…

【代碼隨想錄算法訓練營——Day10】棧與隊列——232.用棧實現隊列、225.用隊列實現棧、20.有效的括號、1047.刪除字符串中的所有相鄰重復項

LeetCode題目鏈接 https://leetcode.cn/problems/implement-queue-using-stacks/ https://leetcode.cn/problems/implement-stack-using-queues/description/ https://leetcode.cn/problems/valid-parentheses/description/ https://leetcode.cn/problems/remove-all-adjacent-…

Asp .Net Core 系列:Asp .Net Core 集成 Hangfire+MySQL

在 .NET 或 .NET Core 應用中&#xff0c;若需在不依賴 Windows 服務、獨立進程的前提下實現后臺處理&#xff0c;Hangfire 是最成熟、簡單的方案之一 —— 它可直接嵌入現有應用&#xff08;如 ASP.NET Core Web 應用&#xff09;&#xff0c;無需額外部署&#xff0c;同時提供…

網站漏洞掃描要怎么處理?

在網絡安全領域&#xff0c;網站漏洞是黑客攻擊的重要突破口&#xff0c;而網站漏洞掃描能及時發現這些隱患。但很多小白在完成漏洞掃描后&#xff0c;不清楚后續該如何處理&#xff0c;導致漏洞一直存在&#xff0c;給網站安全埋下風險。下面從準備工作、處理步驟、驗證維護等…

淘寶RecGPT:通過LLM增強推薦

導論背景 (Background)??推薦系統的核心挑戰??&#xff1a;怎么 準確推斷 用戶行為背后快速變化的真實意圖&#xff0c;以實現用戶、商戶和平臺的三贏。??現有方法的局限性??&#xff1a;傳統的基于歷史日志共現模式&#xff08;“從點擊學習點擊”&#xff09;的模型&…

【Go系統編程】07 網絡化IPC:Go的王牌——Socket編程

大家好&#xff0c;我是Tony Bai。歡迎來到我們《Go 系統編程》專欄的最后一講。在過去的旅程中&#xff0c;我們探索了管道、消息隊列、共享內存等一系列強大的 IPC 機制。它們各有所長&#xff0c;但都有一個共同的、致命的局限性&#xff1a;它們都只能在同一臺物理機上工作…

claude code使用小竅門

視頻地址 B站 1 /init 在項目最開始的時候&#xff0c;使用/init可以將項目通讀一遍。cc會將學習到的關于項目的知識都保存到CLAUD.MD文件中 2、 /compact 用來壓縮對話的上下文&#xff0c;claude會將之前的一些亂七八糟或者重復的對話刪除壓縮&#xff0c;有利于提高AI的…

The learning process of Decision Tree Model|決策樹模型學習過程

----------------------------------------------------------------------------------------------- 這是我在我的網站中截取的文章&#xff0c;有更多的文章歡迎來訪問我自己的博客網站rn.berlinlian.cn&#xff0c;這里還有很多有關計算機的知識&#xff0c;歡迎進行留言或…

期貨盤后空開是認購期權行權?

本文主要介紹期貨盤后空開是認購期權行權&#xff1f;期貨盤后空開與認購期權行權是兩個獨立的概念&#xff0c;無直接關聯&#xff0c;需從交易機制、操作邏輯及市場規則三方面區分。期貨盤后空開是認購期權行權&#xff1f;1. 定義與交易屬性期貨盤后空開&#xff1a;屬于期貨…

ESP32 I2S音頻總線學習筆記(七):制作一個錄音播放器

簡介 上一篇我們利用I2S輸出DIY了一個藍牙音箱簡單玩了一下&#xff0c;本篇我們繼續來看代碼。前面幾篇文章我們分別介紹了I2S輸入&#xff0c;I2S輸出&#xff0c;以及WAV文件格式的相關內容&#xff0c;那我們就可以根據所學到的&#xff0c;制作一個錄音機&#xff0c;具體…

PyTorch 動態圖的靈活性與實用技巧

PyTorch 以其動態計算圖&#xff08;Dynamic Computation Graph&#xff09;而聞名&#xff0c;這賦予了它極高的靈活性和易用性&#xff0c;使其在研究和實際應用中都備受青睞。與TensorFlow 1.x的靜態圖&#xff08;需要先定義圖結構&#xff0c;再運行&#xff09;不同&…

#C語言——刷題攻略:牛客編程入門訓練(十一):攻克 循環控制(三),輕松拿捏!

&#x1f31f;菜鳥主頁&#xff1a;晨非辰的主頁 &#x1f440;學習專欄&#xff1a;《C語言刷題合集》 &#x1f4aa;學習階段&#xff1a;C語言方向初學者 ?名言欣賞&#xff1a;"代碼行數決定你的下限&#xff0c;算法思維決定你的上限。" 前言&#xff1a;在學習…

復雜PDF文檔結構化提取全攻略——從OCR到大模型知識庫構建

在學術研究、金融分析、法律合同、工程設計等眾多領域&#xff0c;PDF文檔已成為信息存儲與傳遞的重要載體。然而&#xff0c;面對包含復雜表格、公式、圖表、手寫批注、多欄排版等元素的PDF&#xff0c;傳統工具往往難以準確、完整地提取內容。這不僅影響信息利用效率&#xf…

HttpClient、OkHttp 和 WebClient

HttpClient、OkHttp 和 WebClient 是 Java 生態中常見的 HTTP 客戶端&#xff0c;它們在設計理念、異步能力、性能等方面有所不同。以下是它們的詳細對比&#xff1a;1. 概述客戶端介紹Apache HttpClient傳統同步 HTTP 客戶端&#xff0c;功能豐富&#xff0c;歷史悠久&#xf…

書籍成長書籍文字#創業付費雜志《財新周刊》2025最新合集 更33期

免費訪問地址 https://isharehubs.com/article/2025-33-26c27ee5bb9180cdafc5efbec9545ac5 資源信息 付費雜志《財新周刊》2025最新合集 更33期 《財新周刊》2025 最新合集&#xff08;更至 33 期&#xff09;重磅上線&#xff0c;聚焦年度熱點與結構性變化&#xff0c;從監…

用python的socket寫一個局域網傳輸文件的程序

局域網傳輸文件是最最常用的功能&#xff0c;我參考https://www.jb51.net/python/345837qrz.htm這篇文章&#xff0c;復制粘貼&#xff0c;開發了一個。但發現進度條沒有用&#xff0c;也沒有顯示傳輸用時和傳輸速度的功能&#xff0c;于是我改寫了代碼&#xff0c;使它實現這個…