1. 空白窗口
在 PyCharm 中創(chuàng)建一個(gè)名為 TutorialApp 的項(xiàng)目,然后在該項(xiàng)目中新建了個(gè)名為 tutorial_app.py 的 Python 源文件,在 PyCharm 的代碼編輯器中,輸入下面的代碼:
from kivy.app import App
class TutorialApp(App):
pass
if __name__ == "__main__":
TutorialApp().run()
雖然只有寥寥數(shù)行代碼,但這已經(jīng)是一個(gè)可以運(yùn)行的 Kivy 應(yīng)用了!
運(yùn)行這段代碼,將顯示出一個(gè)黑色的窗口。雖然簡單,但已經(jīng)是一個(gè)標(biāo)準(zhǔn)的窗口了。你可以移動(dòng)窗口、改變窗口大小、最大化、最小化,以及關(guān)閉窗口。

第 1 行 from kivy.app import App 導(dǎo)入 kivy 的 App 類,它是所有 kivy 應(yīng)用的基類。
我們繼承 App 類,派生出TutorialApp 類(第 3, 4 行)。我們還沒有給 TutorialApp 添加任何方法,但它從 App 類中繼承了 kivy 應(yīng)用最基本的方法,如創(chuàng)建窗口、設(shè)置窗口的大小和位置等。
最后,要讓 kivy 應(yīng)用真正跑起來,我們需要?jiǎng)?chuàng)建 TutorialApp 對(duì)象,并調(diào)用它的 run 方法(第 7 行)。
2. 添加控件 (widget)
一個(gè)光禿禿的窗口是沒啥用的,我們還得在窗口上放置一些控件(widget)。Kivy 內(nèi)置了豐富的控件,如按鈕 (button), 復(fù)選框 (checkbox), 標(biāo)簽 (label), 輸入框 (textinput), 滾動(dòng)容器 (scrollable container) 等。
這里咱們不妨先試試比較簡單的按鈕控件 (button)。
from kivy.app import App
from kivy.uix.button import Button
class TutorialApp(App):
def build(self):
return Button()
if __name__ == "__main__":
TutorialApp().run()
運(yùn)行修改后的程序,乍看上去,似乎是窗口的背景從黑色變成了灰色。實(shí)際上是整個(gè)窗口被一個(gè)巨大的按鈕填滿了,不信你用鼠標(biāo)點(diǎn)擊試試?看到背景顏色變化了嗎?這表明,你點(diǎn)擊的是一個(gè)巨大的按鈕,而不是窗口本身。

第 2 行 from kivy.uix.button import Button 導(dǎo)入 kivy 的按鈕控件 Button。
第 5, 6 行,我們實(shí)現(xiàn)了 TutorialApp 類的 build 方法(繼承自 App 類)。build 方法返回一個(gè)按鈕 (Button) 對(duì)象。build 方法返回的控件,在 Kivy 中,稱之為“根控件” (root widget)。Kivy 將自動(dòng)縮放根控件,讓它填滿整個(gè)窗口。這就是為什么我們會(huì)得到一個(gè)充滿整個(gè)窗口的巨型按鈕。
我們還可以在創(chuàng)建按鈕時(shí)傳遞參數(shù),讓它變得更生動(dòng)一些。
from kivy.app import App
from kivy.uix.button import Button
class TutorialApp(App):
def build(self):
return Button(text='iPaoMi', background_color=(0, 0, 1, 1), font_size=150)
if __name__ == "__main__":
TutorialApp().run()
例如,我們可以將按鈕的背景色設(shè)置為藍(lán)色,并在按鈕上以 150 的字號(hào),顯示文字 iPaoMi (第 6 行)。其中,參數(shù) background_color 接受的 4 元組,分別表示 RGBA 顏色的 4 個(gè)分量。

3. 多點(diǎn)觸控
現(xiàn)在,我們的應(yīng)用還非常地簡單,幾乎沒有什么交互。而且,其他許多 GUI 庫,例如 QT, GTK 等也可以很容易地做出類似的效果,實(shí)在看不出 Kivy 究竟有何過人之處。接下來,咪博士將向大家展示如何快速實(shí)現(xiàn)多點(diǎn)觸控的操作,你將看到為什么我們說 Kivy 是為移動(dòng)應(yīng)用而生。
這一節(jié)中,我們將會(huì)用到 2 個(gè) Kivy 控件:Scatter 和 Label。
- Scatter 是實(shí)現(xiàn)多點(diǎn)觸控的關(guān)鍵,它可以方便地實(shí)現(xiàn)移動(dòng)、縮放,以及旋轉(zhuǎn)的操作
- Label 是用來顯示文字的,我們將它放在 Scatter 上,從而實(shí)現(xiàn)對(duì)文字的移動(dòng)、縮放和旋轉(zhuǎn)的操作
最終,我們修改后的代碼如下:
from kivy.app import App
from kivy.uix.scatter import Scatter
from kivy.uix.label import Label
class TutorialApp(App):
def build(self):
s = Scatter()
l = Label(text='iPaoMi', font_size=150)
s.add_widget(l)
return s
if __name__ == "__main__":
TutorialApp().run()
運(yùn)行程序,我們看到窗口左下角顯示了一些字符串。

我們可以用鼠標(biāo)左鍵把左下角的字符串拖動(dòng)到窗口中央。

我們可以用鼠標(biāo)右鍵來模擬手機(jī)屏幕上多點(diǎn)觸控的操作。用鼠標(biāo)右鍵在字符串上點(diǎn)擊,會(huì)顯示一個(gè)紅色的小圓點(diǎn),表示一個(gè)觸控點(diǎn)的位置。我們?cè)谧址?2 個(gè)不同位置,用鼠標(biāo)右鍵點(diǎn)擊,形成 2 個(gè)觸控點(diǎn)。然后,嘗試用鼠標(biāo)左鍵去拖動(dòng)字符串,你會(huì)發(fā)現(xiàn)字符串發(fā)生了旋轉(zhuǎn)和縮放!

最后,讓咪博士為大家講解一下代碼吧。
第 2, 3, 4 行分別導(dǎo)入 Scatter 和 Label 控件
第 7, 8 行分別創(chuàng)建了 Scatter 和 Label 控件實(shí)例
第 9 行 s.add_widget(l) 將 Label 控件實(shí)例添加到 Scatter 控件實(shí)例中。這樣用戶的操作直接影響 Scatter 控件,再由 Scatter 自動(dòng)將這些影響作用到它內(nèi)部的子控件(即 Label 控件)上。
第 10 行 return s 將 Scatter 實(shí)例作為根控件返回。Kivy 會(huì)自動(dòng)用根控件(Scatter 實(shí)例)填充整個(gè)窗口。
Kivy 的設(shè)計(jì)中充分考慮了移動(dòng)應(yīng)用的交互,這是 Kivy 與其他 GUI 庫 (如 QT, GTK) 最重要的區(qū)別。當(dāng)然,用鼠標(biāo)來模擬多點(diǎn)觸控的操作顯得很不自然。后面的教程中,咪博士將教大家,如何將 Kivy 應(yīng)用打包并運(yùn)行在手機(jī)上。屆時(shí),大家將真正見識(shí)到 Kivy 在移動(dòng)應(yīng)用開發(fā)中的威力。