Kivy A to Z -- Kivy的訊息處理機制
外面一直在下雨,比較無聊,順便總結了下Kivy的訊息的處理過程。
總的來說,在Kivy裡,處理的訊息一共有四種:按鍵訊息,滑鼠訊息,觸屏訊息,還有自定義訊息。下面來看下整個訊息的處理流程。
先來看張圖:
先來解釋下這幾個類都是幹嘛的:
1、EventDispatcher:看名稱就知道這是一個訊息分發類,在這個類中通過了以下的主要方法:
register_event_type : 註冊一種訊息型別
bind :將一個方法繫結到一個訊息型別,用於儲存方法的是一個list型別。
dispatch :呼叫相應的已經註冊到指定訊息型別的方法。
2、WindowBase:Window的基類,定義了Window的一些常用的方法,如add_wdiget,on_draw。
WindowPygame,WindowX11,WindowSDL這三個類是WindowBase的子類,在某一平臺上只會初始化一種,並且只有一個例項,主要用於接收訊息和處理訊息。具體的初始化程式碼在kivy/core/__init__.py:
#: Instance of a :class:`WindowBase` implementation Window = core_select_lib('window', ( ('egl_rpi', 'window_egl_rpi', 'WindowEglRpi'), ('pygame', 'window_pygame', 'WindowPygame'), ('sdl', 'window_sdl', 'WindowSDL'), ('x11', 'window_x11', 'WindowX11'), ), True)
如果沒有特別指定,Kivy將會例項化WindowPygame,作為Kivy的主視窗。所有的畫圖,建立widget的操作都將在這個主視窗上進行。
再來解釋下主要變數和方法。EventDispatcher.__event_stack,這是一個用於儲存所有已經註冊的訊息。新增一個訊息到__event_stack有兩種方法:
1、一種是通過呼叫EventDispatcher.register_event_type
2、另一種方法是在子類中宣告一個類變數__events__,如在WindowBase中就有關於__events__的宣告:
__events__ = ('on_draw', 'on_flip', 'on_rotate', 'on_resize', 'on_close', 'on_motion', 'on_touch_down', 'on_touch_move', 'on_touch_up', 'on_mouse_down', 'on_mouse_move', 'on_mouse_up', 'on_keyboard', 'on_key_down', 'on_key_up', 'on_dropfile')
並在EventDispatcher.__cinit__時把這些事件型別加到__event_stack變數中。
有了事件的型別,接下來要做的事就是通過EventDispatcher.bind新增事件的處理方法:
例如,在input/providers/mouse.py的MouseMotionEventProvider中,就有下面的bind程式碼:
def start(self):
'''Start the mouse provider'''
if not EventLoop.window:
return
EventLoop.window.bind(
on_mouse_move=self.on_mouse_motion,
on_mouse_down=self.on_mouse_press,
on_mouse_up=self.on_mouse_release)
好,註冊了訊息型別和訊息的處理過程,按下來就要等訊息上門了。
前面講到,Kivy例項化了WindowPygame作為主視窗,並且通過呼叫App.run最終進入WindowPygame._mainloop這個訊息迴圈方法。接下來看下_mainloop都做了些什麼:
def _mainloop(self):
EventLoop.idle()
for event in pygame.event.get():
# kill application (SIG_TERM)
if event.type == pygame.QUIT:
EventLoop.quit = True
self.close()
# mouse move
elif event.type == pygame.MOUSEMOTION:
x, y = event.pos
self.mouse_pos = x, self.system_size[1] - y
# don't dispatch motion if no button are pressed
if event.buttons == (0, 0, 0):
continue
self._mouse_x = x
self._mouse_y = y
self._mouse_meta = self.modifiers
self.dispatch('on_mouse_move', x, y, self.modifiers)
# mouse action
elif event.type in (pygame.MOUSEBUTTONDOWN,
pygame.MOUSEBUTTONUP):
self._pygame_update_modifiers()
x, y = event.pos
btn = 'left'
if event.button == 3:
btn = 'right'
elif event.button == 2:
btn = 'middle'
elif event.button == 4:
btn = 'scrolldown'
elif event.button == 5:
btn = 'scrollup'
elif event.button == 6:
btn = 'scrollright'
elif event.button == 7:
btn = 'scrollleft'
eventname = 'on_mouse_down'
if event.type == pygame.MOUSEBUTTONUP:
eventname = 'on_mouse_up'
self._mouse_x = x
self._mouse_y = y
self._mouse_meta = self.modifiers
self._mouse_btn = btn
self._mouse_down = eventname == 'on_mouse_down'
self.dispatch(eventname, x, y, btn, self.modifiers)
# keyboard action
elif event.type in (pygame.KEYDOWN, pygame.KEYUP):
self._pygame_update_modifiers(event.mod)
# atm, don't handle keyup
if event.type == pygame.KEYUP:
self.dispatch('on_key_up', event.key,
event.scancode)
continue
# don't dispatch more key if down event is accepted
if self.dispatch('on_key_down', event.key,
event.scancode, event.unicode,
self.modifiers):
continue
self.dispatch('on_keyboard', event.key,
event.scancode, event.unicode,
self.modifiers)
# video resize
elif event.type == pygame.VIDEORESIZE:
self._size = event.size
self.update_viewport()
elif event.type == pygame.VIDEOEXPOSE:
self.canvas.ask_update()
# ignored event
elif event.type == pygame.ACTIVEEVENT:
pass
# drop file (pygame patch needed)
elif event.type == pygame.USEREVENT and \
hasattr(pygame, 'USEREVENT_DROPFILE') and \
event.code == pygame.USEREVENT_DROPFILE:
self.dispatch('on_dropfile', event.filename)
'''
# unhandled event !
else:
Logger.debug('WinPygame: Unhandled event %s' % str(event))
在這個訊息迴圈裡,通過pygame.event.get()獲取訊息,訊息的型別有:按鍵,滑鼠,這兩種,通過dispatch將訊息傳送到相應的方法中去處理,這裡有一個疑問:怎麼沒有看到Kivy對觸屏訊息的處理?答案是觸屏訊息的處理是在函式開始的EventLoop.idle()裡進行的。這篇講的就要是訊息的處理機制,所以這裡就不再展來。其內容留著以後再講。
相關推薦
Kivy A to Z -- Kivy的訊息處理機制
外面一直在下雨,比較無聊,順便總結了下Kivy的訊息的處理過程。 總的來說,在Kivy裡,處理的訊息一共有四種:按鍵訊息,滑鼠訊息,觸屏訊息,還有自定義訊息。下面來看下整個訊息的處理流程。 先來看張圖: 先來解釋下這幾個類都是幹嘛的: 1、EventDis
Kivy A to Z -- Kivy的執行機制
1. 當看到一個在Android平臺上執行的Python程式時,我的第一個好奇的地方就是它究竟是怎麼做到的。 2. 好,費話少說,我們通過原始碼來分析一下。 3. 首先從dist/default匯入工程,如圖所示: 4. 接下來我們來理順一下整個的Python程式的
Kivy a to z -- Kivy的編譯過程-distribute.sh指令碼分析
1 這一節重點來分析一下distribute.sh,以此來了解一下Kivy的整個編譯過程 2 在上一篇文章中,我們講到編譯的方法: ./distribute.sh -m 'openssl pyjnius pil kivy' 3 那整個過程是怎麼進行的,下面來分析一下: 4
詳解 Handler 訊息處理機制(附自整理超全 Q&A)
Android 為什麼要用訊息處理機制 如果有多個執行緒更新 UI,並且沒有加鎖處理,會導致介面更新的錯亂,而如果每個更新操作都進行加鎖處理,那麼必然會造成效能的下降。所以在 Android 開發中,為了使 UI 操作是執行緒安全的,規定只許主執行緒即 UI 執行緒可以更新 UI 元件。但實際開發中,常常會遇
android 非同步訊息處理機制 — AHandler
1. 引入 ALooper、AHandler、AMessage 在 android multimedia stagefright 的框架程式碼中,通篇都是這幾個類的身影,所以熟悉 android 多媒體框架的第一步必須理解這幾個類的含義。 這幾個類是為了實現非同步訊息機制而設計的
Android非同步訊息處理機制詳解及原始碼分析
PS一句:最終還是選擇CSDN來整理髮表這幾年的知識點,該文章平行遷移到CSDN。因為CSDN也支援MarkDown語法了,牛逼啊! 【工匠若水 http://blog.csdn.net/yanbober 轉載煩請註明出處,尊重分享成果】 最近相對來說比較閒,加上養病,所
Android之訊息處理機制(二)Handler的本質-Message和Looper到底是什麼?
目錄 Android之訊息處理機制(二) 以下皆為乾貨,比較幹,需要讀者細細理解。 前面(一)已經解釋了Handler的基本機制了,下面來概括一下本質。 一、MessageQueue MessageQueue其實就
C# 訊息處理機制及自定義過濾方式
一、訊息概述 Windows 下應用程式的執行是通過訊息驅動的。訊息是整個應用程式的工作引擎,我們需要理解掌握我們使用的程式語言是如何封裝訊息的原理。1. 什麼是訊息(Message) 訊息就是通知和命令。在.NET框架類庫中的System.Windows.Forms名稱
Android非同步訊息處理機制:Looper、Handler、Message
1 簡介 Handler,Looper,Message這三者都與Android非同步訊息處理執行緒相關, Looper:負責建立一個MessageQueue,然後進入一個無限迴圈體不斷從該MessageQueue中讀取訊息; Handler:訊息建立者,一個或者多個
ActiveMQ(二)——訊息處理機制
一、前言 上文中,小編提到安裝ActiveMQ,但是對於ActiveMQ中訊息是用什麼樣的形式儲存的?下面小編就向大家介紹一下。 二、訊息型別 對於訊息的傳遞有兩種型別: 1.點對點的,即一個生產者和一個消費者一一對應; 2.釋出/訂閱模式,即一個生產者產生訊
淺談Android的訊息處理機制--Handler
1.為什麼有Handler? 在UI執行緒中不能進行耗時操作,例如資料讀寫、網路請求、圖片載入等,所以這些操作被放在子執行緒裡,Handler便是子執行緒和UI執行緒之間通訊的橋樑之一。 2.幹什麼用的? 進行非同步訊息處理,即上述內容。 3.Handler類裡面有什麼是必須知道
android的訊息處理機制——Looper,Handler,Message (原理圖、原始碼)
轉自:http://my.oschina.net/u/1391648/blog/282892 在開始討論android的訊息處理機制前,先來談談一些基本相關的術語。 通訊的同步(Synchronous):指向客戶端傳送請求後,必須要在服務端有迴應後客戶端才繼續傳送
Android Handler 非同步訊息處理機制的妙用 建立強大的圖片載入類
最近建立了一個群,方便大家交流,群號:55032675上一篇部落格介紹了Android非同步訊息處理機制,如果你還不瞭解,可以看:Android 非同步訊息處理機制 讓你深入理解 Looper、Handler、Message三者關係 。那篇部落格的最後,提出可以把非同步訊息處理
【Android 開發】: Android 訊息處理機制之四: Android 訊息迴圈 Looper 及其原始碼解析
上一講我們學習Handler和Message的一些使用方式,我們知道Handler它會發送訊息和處理訊息,並且關聯一個子執行緒,如何傳送訊息入隊和出隊處理訊息等這些都是交給Looper去管理分發的,也就是它是負責整個訊息佇列運轉的一個類,這一講我們就來學習一下Andr
Android的訊息處理機制:Message、Handlerhe和Looper原始碼解析
android的訊息處理有三個核心類:Looper,Handler和Message。其實還有一個Message Queue(訊息佇列),但是MQ被封裝到Looper裡面了,我們不會直接與MQ打交道,因此我沒將其作為核心類。下面一一介紹: 執行緒的魔法師 Looper Loo
圖文解析Android 訊息處理機制
之前也看過不少的書或部落格介紹Android 訊息處理機制的知識點,但總是剛看完感覺懂了,過幾天就忘,今天一邊看原始碼,一邊畫了類圖和時序圖,希望可以加深自己的理解。 Android應用啟動時會
Android中的非同步訊息處理機制
這也是Android中老生常談的一個話題了,它本身並不是很複雜,可是面試官比較喜歡問。本文就從原始碼再簡單的理一下這個機制。也可以說是理一下Handler、Looper、MessageQueue之間的關係。 單執行緒中的訊息處理機制的實現 首先我們以Looper.java原始碼中給出的一個例子來
【Android 開發】: Android 訊息處理機制之三: Handler 中 sendMessage() 原始碼剖析
閱讀此文,請先閱讀以下相關連線: sendMessage()的幾種過載方法的使用方式的不同以及它們的原始碼的剖析. 通過前面幾講的內容,我們知道Android不但可以使用非同步任務處理多執行
Android架構分析之Android訊息處理機制(二)
作者:劉昊昱 Android版本:4.4.2 在上一篇文章中我們看了一個使用Handler處理Message訊息的例子,本文我們來分析一下其背後隱藏的Android訊息處理機制。 我們可能比較熟悉Windows作業系統的訊息處理模型: while(GetMessage
解析非同步訊息處理機制
Android 中的非同步訊息處理主要有四部分組成:Meeage、Handler、MessageQueue 和 Looper。其中Meeage 是執行緒之間傳遞的訊息,它可以攜帶少量的資訊,用於在不同執行緒之間交換資料。Handler是傳送和處理訊息的。傳送訊息一般是使用