四瞻坝、編程向導(4.6輸入管理)

編程向導4.6輸入管理

一蛛壳、輸入架構

Kivy能處理很多類型的輸入:鼠標、觸摸屏所刀、加速器衙荐、陀螺儀等等。它在下列的平臺中能處理多點觸摸協(xié)議:Tuio浮创,WM_Touch, MacMultitouchSupport, MT Protocol A/B and Android.

輸入全局架構可以被描述為:

輸入提供者(Input Providers) -> 運動事件(Motion event) -> 投遞處理(Post processing) -> 發(fā)送到窗口(Dispatch to Window)

所有管理輸入事件的類是運動事件(MotionEvent)忧吟。它派生成兩種類型的事件類:

  • 觸摸事件:一個運動事件能至少包含X和Y坐標。所有的觸摸事件通過部件樹進行發(fā)送斩披。

  • 非觸摸事件:剩下的溜族,例如加速器是一個連續(xù)事件,沒有坐標垦沉。它沒有開始和停止狀態(tài)煌抒。這些事件不通過部件樹發(fā)送。

一個運動事件被一個輸入提供者(Input Provider)生成厕倍。一個輸入提供者負責從操作系統(tǒng)寡壮、網(wǎng)絡或其他應用程序讀取輸入事件。下是幾個輸入提供者:

  • TuioMotionEventProvider:創(chuàng)建一個UDP服務并監(jiān)聽TUIO/OSC消息讹弯。

  • WM_MotionEventProvider:使用窗口API讀取多點觸摸信息并發(fā)送到Kivy诬像。

  • ProbeSysfsHardwareProbe:在Linux系統(tǒng)下,迭代所有連接到計算機上的硬件闸婴,并附著一個多點輸入提供者為每一個被發(fā)現(xiàn)的多點觸摸設備坏挠。

  • 更多:...
    當你寫一個應用程序時,你不必創(chuàng)建一個輸入提供者邪乍,Kivy會嘗試自動檢測可用的硬件降狠。但是对竣,如果你想支持定制的硬件,你就需要配置Kivy并使它工作榜配。

在新創(chuàng)建的運動事件被傳遞到用戶之前否纬,Kivy應用投遞處理(post-processing)到輸入。每一個運動事件被分析并糾正錯誤輸入蛋褥,做出有意義的解釋:

  • 通過距離和時間臨界值临燃,檢測雙擊/三擊(Double/triple-tap detection)。
  • 當硬件不是太精確時烙心,使得事件更精確膜廊。
  • 如果本地觸摸硬件在基本相同的位置發(fā)送多個事件時,降低事件的數(shù)量淫茵。

當處理事件后爪瓜,運動事件被發(fā)送到窗口。正如前面解釋的那樣匙瘪,不是所有的事件都發(fā)送到事件樹:窗口過濾它們铆铆。對于一個事件:

  • 如果它僅僅是一個運動事件,它會被發(fā)送到on_motion()

  • 如果它是一個觸摸事件丹喻,則觸摸點的(x, y)坐標(在0-1范圍內(nèi))會被重新轉換為屏幕尺寸(寬/高)薄货,并發(fā)送到:

    • on_touch_down()
    • on_touch_move()
    • on_touch_up()

二、運動事件配置

依賴你的硬件和使用的輸入提供者碍论,也許有更多的信息可以被使用菲驴。例如,觸摸輸入有(x, y)坐標骑冗,但是也許還有壓力信息赊瞬,觸摸尺寸,加速度等等贼涩。

一個運動事件配置是一個標識事件里面有什么特征可用字符串巧涧,讓我們想象一下你在on_touch_move方法中:

def on_touch_move(self, touch):
    print(touch.profile)
    return super(..., self).on_touch_move(touch)

打印信息為:

['pos', 'angle']

注意:很多人將配置的名字和屬性對應的名字混淆在了一塊。在可用的配置文件里的'angle'不意味著觸摸事件對象有一個angle對象遥倦。

對于'pos'配置谤绳,屬性pox, x, y是可用的。對于'angle'配置袒哥,屬性 a 是可用的缩筛。正如我們所說,對于觸摸事件堡称,'pos'是一個托管的配置瞎抛,但'angle'不是。你能通過檢測'angle'配置是否存在來擴展你的交互:

def on_touch_move(self, touch):
    print('the touch is at position', touch.pos)
    if 'angle' in touch.profile:
        print('the touch angle is', touch.a)

你能在motionevent文檔中找到一個關于可用的配置的列表却紧。

三桐臊、觸摸事件

一個觸摸事件是一個特殊的運動事件胎撤,它的屬性is_touch被設置為True。對于所有的觸摸事件断凶,你會自動擁有X和Y坐標伤提,對應著窗口的寬和高。換句話說认烁,所有的觸摸事件有'pox'配置肿男。

(一)觸摸事件基礎

默認情況下,觸摸事件被發(fā)送到當前所有的可顯示的部件却嗡。這意味著無論事件發(fā)生在部件的內(nèi)部與否舶沛,它都能收到事件。

如果你有關于其他GUI的開發(fā)經(jīng)驗稽穆,這可能是反直覺的冠王。一般典型的做法是劃分屏幕為幾何區(qū)域赶撰,并且只有坐標在部件區(qū)域內(nèi)部時才發(fā)送觸摸或鼠標事件到部件舌镶。

當使用觸摸事件工作時,這個要求變得非常的有限制性豪娜。強擊餐胀,縮放和長按可能來自想了解部件及其如何反應的外部。

為了提供最大的靈活性瘤载,Kivy發(fā)送事件到所有的部件否灾,并讓它們決定是否響應它們。如果你僅想在部件內(nèi)部響應觸摸事件鸣奔,你可以簡單的進行檢測:

def on_touch_down(self, touch):
    if self.collide_point(*touch.pos):
        #觸摸發(fā)生在部件區(qū)域的內(nèi)部墨技,做自己的相應
        pass
(二)坐標

一旦你使用了一個帶有矩陣轉換的部件,你必須注意矩陣轉換挎狸。一些部件扣汪,例如分散(Scatter)有它們自己的矩陣轉換,這意味著觸摸必須能正確的傳遞觸摸坐標到Scatter的子部件锨匆。

  • 從父空間到局部空間獲取坐標使用to_local()
  • 從局部空間到父空間獲取坐標使用to_parent()
  • 從局部空間到window空間使用:to_window()
  • 從window空間到局部空間使用:to_widget()

你必須根據(jù)上下文使用上面的一個來轉換相應的坐標崭别。看分散(scatter)的實現(xiàn):

def on_touch_down(self, touch):
    #將當前的坐標壓入恐锣,為了后面能存儲它
    touch.push()

    #轉換觸摸坐標到局部坐標
    touch.apply_transform_2d(self.to_local)

    #像平時一樣茅主,發(fā)送觸摸到子部件
    #在touch里面的坐標是局部坐標
    ret = super(..., self).on_touch_down(touch)

    #無論結果如何,不要忘記調(diào)用之后彈出你的轉換土榴,
    #這樣诀姚,坐標會變成父坐標
    touch.pop()

    #返回結果(依賴于你的所需)
    return ret

(三)觸摸形狀

如果觸摸有一個形狀,它可以在'shape'屬性中體現(xiàn)$枨荩現(xiàn)在学搜,僅僅ShapeRect被暴露:

from kivy.input.shape import ShapeRect

def on_touch_move(self,touch):
    if isinstance(touch.shape, ShapeRect):
        print('My touch have a rectangle shape of size', 
            (touch.shape.width, touch.shape.height))
(四)雙擊

雙擊是指在一段時間和范圍內(nèi)輕點兩次娃善。它由doubletap post-processing模塊來計算。你能測試當前的觸摸是雙擊或不是:

def on_touch_down(self, touch):
    if touch.is_double_tap:
        print('touch is a double tap!')
        print('- interval is', touch.double_tab_time)
        print('- distance between previous is', touch.double_tap_distance)
(五)三擊

三擊是只在一段時間和一定范圍內(nèi)輕擊三次瑞佩。它由tripletap post-processing模塊來計算聚磺。你能測試當前的觸摸是否為三擊:

def on_touch_down(self, touch):
    if touch.is_triple_tap:
        print('Touch is a triple tap !')
        print(' - interval is', touch.triple_tap_time)
        print(' - distance between previous is', touch.triple_tap_distance)
(六)捕獲觸摸事件

對于父部件使用on_touch_down發(fā)送一個觸摸事件到子部件,它是可能的炬丸,但通過on_touch_moveon_touch_up就不可以瘫寝。這可能發(fā)生在特定的場景下,例如當一個觸摸事件發(fā)生在父部件邊框外部時稠炬,父部件決定不通知它的子部件焕阿。

當你捕獲了一個事件,你會總是收到移動(move)和彈起(up)事件首启,但是對于捕獲有一些限制:

  • 你將會收到事件至少兩次:一次來自你的父部件(正常事件)暮屡,一次來自window(捕獲)。
  • 你可能收到一個事件毅桃,但是不是來自你:它可能因為父部件發(fā)送給它的子部件褒纲。
  • 觸摸坐標沒有轉換到你的部件空間,因為觸摸是來自Window钥飞。你需要收動轉換它們莺掠。

下面是一個例子來演示如何使用捕獲:

def on_touch_down(self, touch):
    if self.collide_point(*touch.pos):

        #如果觸摸檢測來自我們自己的部件,讓我們捕獲它读宙。
        touch.grab(self)
        # 并響應這次觸摸.
        return True

def on_touch_up(self, touch):
    #這里彻秆,你不用檢測觸摸碰撞或類似操作,
    #你僅需要檢測是否它是一個捕獲的觸摸事件
    if touch.grab_current is self:
        #OK结闸,當前觸摸事件被派發(fā)給我們
        #做一些感興趣的操作
        print('Hello world!')
        #不要忘記釋放掉唇兑,否則可能會有副作用
        touch.ungrab(self)
        #最后響應這次觸摸
        return True
(七)觸摸事件管理

為了了解觸摸事件如何在部件間被控制和傳播,請參閱部件觸摸事件冒泡機制(Widget touch event bubbling)

下節(jié)預告:編程向導4.7部件

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末桦锄,一起剝皮案震驚了整個濱河市扎附,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌察纯,老刑警劉巖帕棉,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異饼记,居然都是意外死亡香伴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門具则,熙熙樓的掌柜王于貴愁眉苦臉地迎上來即纲,“玉大人,你說我怎么就攤上這事博肋〉驼” “怎么了蜂厅?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長膊畴。 經(jīng)常有香客問我掘猿,道長,這世上最難降的妖魔是什么唇跨? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任稠通,我火速辦了婚禮,結果婚禮上买猖,老公的妹妹穿的比我還像新娘改橘。我一直安慰自己,他們只是感情好玉控,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布飞主。 她就那樣靜靜地躺著,像睡著了一般高诺。 火紅的嫁衣襯著肌膚如雪碌识。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天懒叛,我揣著相機與錄音丸冕,去河邊找鬼耽梅。 笑死薛窥,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的眼姐。 我是一名探鬼主播诅迷,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼众旗!你這毒婦竟也來了罢杉?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤贡歧,失蹤者是張志新(化名)和其女友劉穎滩租,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體利朵,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡律想,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了绍弟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片技即。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖樟遣,靈堂內(nèi)的尸體忽然破棺而出而叼,到底是詐尸還是另有隱情身笤,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布葵陵,位于F島的核電站液荸,受9級特大地震影響,放射性物質發(fā)生泄漏脱篙。R本人自食惡果不足惜莹弊,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望涡尘。 院中可真熱鬧忍弛,春花似錦、人聲如沸考抄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽川梅。三九已至疯兼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贫途,已是汗流浹背吧彪。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留丢早,地道東北人姨裸。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像怨酝,于是被迫代替她去往敵國和親傀缩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 編程向導4.4架構預覽 我們將要花費一些時間以軟件管理的角度來解釋如何設計Kivy。這將是理解每一部分如何一起工作...
    gthank閱讀 595評論 0 0
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,760評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理斤葱,服務發(fā)現(xiàn)慷垮,斷路器,智...
    卡卡羅2017閱讀 134,629評論 18 139
  • 感恩今天的涼爽天氣揍堕。人胃口也變的特別好了料身。 感恩今天看了一位佛學大師的文章。說的是關于嬰靈的鹤啡。嬰靈的年齡會直到他...
    悅心慧兒閱讀 191評論 0 2
  • 末日微瀾(1) 第二章 星航 若仰望夜空惯驼,遼闊天幕下,我們?nèi)庋鬯姷淖钸h星辰,已經(jīng)存在了138億年祟牲,那些閃耀著的光...
    太陽能植物閱讀 148評論 0 0