【 聲明:版權所有,歡迎轉載,請勿用于商業用途。 聯系信箱:feixiaoxing @163.com】
? ? ? ? 屏幕除了顯示部分,還要去和其他外設進行交互,這是非常重要的一個處理方法。我們知道,不管是mcu,還是linux soc,最重要的處理方法就是狀態機。而狀態機的很重要一個切換條件就是外部輸入,這個輸入有可能是觸屏輸入,有可能是按鍵輸入。通常而言,觸屏輸入是最直接的處理方法。不過觸屏輸入成本稍微高一點,所以很多客戶就會選擇普通的屏幕顯示,再加上物理按鍵的辦法實現人機交互。
1、常用的按鍵個數
? ? ? ? 一般屏幕顯示的話,根據產品要求,按鍵或多或少。按最少的說,大約5個按鍵就能完成大部分功能。這5個按鍵是,上一個、下一個、mode切換、ok確認、返回上一層。
2、按鍵讀取
? ? ? ? 在linux上面,按鍵讀取有很多的方法。第一種,就是直接讀取/sys/class/gpio/gpio0/value這種形式。第二種,就是讀取/dev/input/event0這種方法。第三種一般和廠家的sdk有關系,也就是說,如果廠家有支持按鍵讀取的sdk,直接用他們的也無可厚非。
3、事件類型
? ? ? ? 這里交互的事件大約有兩種,一種是代替觸摸屏的事件,這種情況就是說用按鍵代替ok、cancel這種控件輸入。使用方法就是直接調用lv_obj_send_event函數,比如lv_obj_send_event(btn1, LV_EVENT_CLICKED, NULL)這樣。還有一種就是發送給某個窗口的私有事件,這也是比較常見的做法。就lvgl而言,可以起一個定時器,切換到哪個窗口的時候,就給這個窗口發送消息,只不過對應的消息隊列可能需要自己寫。因為窗口本身只能用定時器+回調函數+消息隊列的方式來實現。
4、舉例說明
? ? ? ? 為了說明按鍵是如何給控件發送消息的,我們可以用定時器代替。假設此時有一個btn,這個btn有一個回調函數btn_ok_cb,那么它的代碼是這樣的,
btn1 = lv_button_create(lv_screen_active()); /*Add a button the current screen*/lv_obj_set_pos(btn1, 200, 250); /*Set its position*/lv_obj_set_size(btn1, 120, 50); /*Set its size*/lv_obj_add_event_cb(btn1, btn_ok_cb, LV_EVENT_ALL, NULL); /*Assign a callback to the button*/lv_obj_t* btn1_label = lv_label_create(btn1); /*Add a label to the button*/lv_label_set_text(btn1_label, "OK"); /*Set the labels text*/lv_obj_center(btn1_label);
? ? ? ? 對應的回調函數如下所示,
static void btn_ok_cb(lv_event_t* e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t* btn = lv_event_get_target_obj(e);if (code == LV_EVENT_CLICKED) {/*Get the first child of the button which is the label and change its text*/lv_obj_t* label = lv_obj_get_child(btn, 0);lv_label_set_text_fmt(label, "clicked: %d", cnt++);}
}
? ? ? ? 這個時候假設有一個按鍵,就可以通過按鍵給btn發送事件。因為目前還是在windows平臺仿真的lvgl,那么可以通過起一個定時器來仿真btn按下。創建定時器的代碼如下所示,
// create timertimer = lv_timer_create(timer_cb1, 1000, &timer);
? ? ? ? 有了定時器,就可以在回調函數里面給btn發送事件了,
static void timer_cb1(lv_timer_t* timer)
{lv_obj_send_event(btn1, LV_EVENT_CLICKED, NULL);
}
? ? ? ? 這樣程序起來之后,定時器就可以模擬按鍵,不停地發送事件了。而btn就好像真的被不停按下,自己就會不停處理事件,進而我們就看到了界面的更新了。