Kivy 中文教程 實例入門 簡易畫板 (Simple Paint App):2. 實現繪圖功能

1. 理解 kivy 坐標系統

上一節中,咪博士帶大家實現了畫板程序的基礎框架,以及一個基本的自定義窗口部件(widget)。在上一節的末尾,咪博士留了一道關于 kivy 坐標系統的思考題給大家。通過點擊窗口的 4 個角落,觀察相應的控制臺輸出,我們可以推斷出 kivy 的坐標原點位于窗口的左下角,x 軸正方向為水平向右,y 軸正方向為豎直向上。這和我們中學數學中常見的平面直角坐標系是一模一樣的。

2. 繪制圓點

了解了 kivy 的坐標系統,本節咪博士將教大家實現簡易畫板的核心功能:繪圖。

重點需要修改的是 MyPaintWidget 的 on_touch_down 方法,同時還要在程序開頭(第 3 行)添加導入顏色和畫圖的函數。修改后的代碼如下:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse
 
 
class MyPaintWidget(Widget):
    def on_touch_down(self, touch):
        with self.canvas:
            Color(1, 1, 0)
            d = 30.
            Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
 
 
class MyPaintApp(App):
    def build(self):
        return MyPaintWidget()
 
 
if __name__ == '__main__':
    MyPaintApp().run()

運行程序,當用鼠標左鍵在窗口上點擊的時候,程序會在鼠標點擊的位置繪制出一個黃色的圓點。


image

第 8 行 with self.canvas:,使用 with 語句進入自定義窗口部件 (MyPaintWidget) 的畫布 (canvas) 上下文。窗口部件 (widget) 的畫布 (canvas) 對應窗口部件在屏幕上的顯示區域,我們可以在上面繪制各種圖形。執行第 8 行代碼之后,后續的繪圖語句就會在這個畫布上繪制出各種圖形了。with 語句還能確保當我們退出畫布上下文的時候,程序自動清理與畫布有關的內部狀態并釋放相應的資源。

第 9 行 Color(1,1,0)將畫筆的顏色設置為黃色。Color 采用 RGB(紅、綠、藍)三原色來表示顏色,每個顏色分量的取值為 [0, 1] 之間。這里我們混合紅色和綠色(第 1, 2 個參數為 1),剔除藍色(第 3 個參數為 0),根據三原色的原理,我們將得到黃色。設置好顏色之后,后續的繪圖都將采用這個顏色,直到你用 Color 函數再次改變顏色。這就好像你用畫筆蘸上黃色的顏料(調用 Color 函數),你隨后畫出的圖案就都是黃色的,一直到你再蘸其他的顏料(再次調用 Color 函數),改變畫筆的顏色。

第 10 行 d=30.設置圓的直徑,后續的代碼將根據變量 d 的值來畫圓。如果,我們想改變圓的大小,只要修改變量 d 的值就可以了,這也是將圓的直徑保存到變量中,給程序帶來的靈活性。

第 11 行 Ellipse(pos=(touch.x - d/2,touch.y - d/2),size=(d,d)) 調用Ellipse 函數在鼠標點擊的位置,按照指定的直徑畫圓。Ellipse 函數中,圓的位置用圓的外切正方形來表示。其中,第 1 個參數 pos 表示外切正方形左下角的坐標(x, y),第 2 個參數 size 表示外切正方形的大?。▽挕⒏撸?。我們想要讓圓心落在鼠標點擊的位置,因此,對應的外切正方形左下角坐標為 (touch.x - d/2,touch.y - d/2)

3. 繪制線條

接著,我們要實現拖拽鼠標繪制線條的功能。代碼如下:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse, Line
 
 
class MyPaintWidget(Widget):
    def on_touch_down(self, touch):
        with self.canvas:
            Color(1, 1, 0)
            d = 30.
            Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
            touch.ud['line'] = Line(points=(touch.x, touch.y))
 
    def on_touch_move(self, touch):
        touch.ud['line'].points += [touch.x, touch.y]
 
 
class MyPaintApp(App):
    def build(self):
        return MyPaintWidget()
 
 
if __name__ == '__main__':
    MyPaintApp().run()

程序運行后的效果像下面這樣


image

第 3 行 from kivy.graphics import Color, Ellipse, Line我們導入函數 Line 用于繪制線條。函數 Line 接受一個由一系列點的坐標所構成的列表,然后依次在相鄰 2 點之間繪制線條。

第 12 行中的 touch.ud 是一個 Python 字典 (dict),我們可以用它來存儲與 touch 事件相關的數據。整個第 12 行 touch.ud['line']=Line(points=(touch.x,touch.y)) 表示的意思是,當鼠標按下時(觸發 on_touch_down 事件),以鼠標點擊的位置 (touch.x, touch.y) 為起點繪制線條(調用 Line 函數),然后將該線條保存到 touch.ud 字典中(對應的 key 值為 ‘line’)。由于,鼠標點擊只能產生 1 個點,而 1 個點是沒有辦法繪制線條的,所以單純的鼠標點擊是無法在屏幕上看到任何線條的。但是,這里確實產生了一個線條,并且我們將它保存到 touch.ud[‘line’] 中,隨后的代碼將繼續往這個線條中添加坐標點,而一系列點的連線就可以顯示出來了。

第 14 行 def on_touch_move(self,touch):添加了一個新的方法 on_touch_move。當用戶拖拽鼠標時,將觸發該函數(執行該函數中的代碼)。一次鼠標拖拽通常會連續多次觸發 on_touch_move 方法,相當于將一次移動拆解成很多個微小的移動,而每一次移動的位置則通過 touch 參數傳遞給 on_touch_move 方法。

第 15 行 touch.ud['line'].points+=[touch.x,touch.y] 將鼠標拖拽產生的坐標點,添加到保存在 touch.ud[‘line’] 中的線條中。

原文鏈接:http://www.ipaomi.com/2017/11/16/kivy-中文教程-實例入門-簡易畫板-simple-paint-app:2-實現繪圖功能/

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,936評論 6 535
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,744評論 3 421
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,879評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,181評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,935評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,325評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,384評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,534評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,084評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,892評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,623評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,322評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,735評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,990評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,800評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,084評論 2 375

推薦閱讀更多精彩內容