def on_touch_move(self, touch):
(x,y) = self.parent.to_parent(touch.x, touch.y)
if self.selected and self.parent.collide_point(x - self.width/2, y - self.height/2):
self.translate(touch.x-self.ix, touch.y-self.iy)
return True
return super(DraggableWidget, self).on_touch_move(touch)
ในส่วนของฟังก์ชั่นด้านบนนั้นการทำงานของฟังก์ชั่นก็คือการให้แน่ใจว่า ตัว widget Draggable นั่นถูกเลือกอยู่ โดยเราจะใช้คำสั่ง collide_point แต่คราวนี้เราจะใช้ parent(DrawingSpace) แทน self เราต้องทำการตรวจสอบตัว parent ซึ่งก็คือ drawingspace เพราะว่าตัว stickman นั้นสามารถลากได้ใน DrawingSpace ไม่ใช่ DraggableWidget มาถึงฟังก์ชั่นต่อไปคือ
def translate(self, x, y):
self.center_x = self.ix = self.ix + x
self.center_y = self.iy = self.iy + y
ฟังก์ชั่นนี้จะทำให้ย้าย DraggableWidget (x,y) พิกเซลโดยทำการใส่ค่าเข้าไปที่ center_x และ center_y ซึ่งฟังก์ชั่นนี้ดูจะไม่ค่อยจำเป็นเท่าไหร่แต่มันจะช่วยเราสามารถใช้คำสั่ง group ได้ง่ายขึ้น
def on_touch_up(self, touch):
if self.selected:
self.unselect()
return True
return super(DraggableWidget, self).on_touch_up(touch)
เป็นฟังก์ชั่นเวลาเราปล่อยเมาส์ออกถ้าเราทำการเลือกตัว Stickman อยู่จะเรียกใช้ฟังก์ชั่น unselect
def unselect(self):
if self.selected:
self.canvas.remove(self.selected)
self.selected = None
ฟังก์ชั่นนี้นั้นจะทำการลบคำสั่ง line ออกจากตัว canvas และกำหนดค่าขึ้นมาใหม่โดนกำหนดให้เป็น None
จากฟังก์ชั่นที่เพิ่มมาทั้งหมดเราก็จะทำการลากตัว Stickman ของเราได้แล้วไปยังส่วนต่อไปคือการเพิ่มตัว Stickman
ก่อนอื่นเราต้องเข้าใจหลักการของ RelativeLayout ก่อนโดยจะมีตัวอย่างจากในรูป
(ภาพจากหนังสือ Kivy interactive application in python)
จากรูปด้านบนนั้นจะเห็นว่ามีหลายสีโดยจะเริ่มจากสีน้ำเงินเป็น parent ของสีเขียว และ สีเขียวเป็น parent ของสีแดง และ layoutสีน้ำเงินเป็นขนาดของหน้าต่างโดยจากรูปเมื่อกี้จะมีมาตรฐานกำหนดไว้ 4 อันที่ class widgets ได้ให้ไว้
1.to_parent () : เมทอดนี้จะทำการเปลี่ยนรูปแบบจุดร่วมกันของ widgets ที่กำหนดกับตัว parent ยกตัวอย่างเช่น a.parent.to_parent(a.x, a.y) จะรีเทิร์นค่ากลับมาเป็น จุดที่ร่วมกันคือ (50,25)
2.to_local(): เป็นเมทอดที่เปลี่ยนรูปแบบจุดร่วมกันระหว่างตัว parent ของมันกับ widgets ปัจจุบันยกตัวอย่าง a.parent.to_local(50,25) จะรีเทิร์นค่ากลับมาเป็นจุดร่วมกันระหว่าง a กับ layout สีแดง
3.to_window(): เมทอดที่ทำการเปลี่ยนรูปแบบจุดร่วมของ widgets ที่เลือกไปเป็น window ยกตัวอย่าง a.to_window(a.x, a.y) จะรีเทิร์นค่ากลับมาคือ 100, 50
4.to_widgets(): เมทอดที่ทำการเปลี่ยนรูปแบบจากจุดร่วมไปเป็นตัวอ widgets ที่เลือกยกตัวอย่าง a.to_widget(100, 50) ก็จะ รีเทรินค่ามาเป็น (0, 0) อีกรอบนึงศึ่งเป็นร่วมกันของ layout สีแดง
อันที่ 3 กับ อันที่ 4 ไม่จำเป็นต้องใช้ parent เพราะตัว Kivy นั้นคิดเอาเองว่า จุดที่ร่วมกันต้อง relative กับ parent เสมอ
ลองดูจากในตัวอย่างที่ในหนังสือให้มาโดยจะทำการเพิ่ม event เข้าไปใน tool box button โดยต้องทำการสร้างไฟล์ .py ขึ้นมาใหม่ คือ toolbox.py โดยโค้ดคือ
โค้ดในไฟล์ toolbox.py
import math
from kivy.uix.togglebutton import ToggleButton
from kivy.graphics import Line
from comicwidgets import StickMan, DraggableWidget
class ToolButton(ToggleButton):
def on_touch_down(self, touch):
ds = self.parent.drawing_space
if self.state == 'down' and ds.collide_point(touch.x, touch.y):
(x, y) = ds.to_widget(touch.x, touch.y)
self.draw(ds, x, y)
return True
return super(ToolButton, self).on_touch_down(touch)
def draw(self, ds, x, y):
pass
จะเห็นได้ว่าตรงส่วนเงี่อนไขคือส่วนที่ตรวจสอบว่าตัว event นั้นเกิดอยู่ในส่วนของ drawingspace
และจะมีโค้ดมาเพิ่มต่อคือ
class ToolStickman(ToolButton):
def draw(self, ds, x, y):
sm = StickMan(width=48, height=48)
sm.center = (x, y)
ds.add_widget(sm)
เราได้สร้างส่วนประกอบของตัว Stickman แล้วก็ได้ทำการใส่ค่าให้ center ด้วยวิธีการ translate จุดร่วมมาถึงจุดนี้เราได้ทำการ add ตัว Stickman เข้าไปนจุดร่วมเรียบร้อยแล้ว
1.to_parent () : เมทอดนี้จะทำการเปลี่ยนรูปแบบจุดร่วมกันของ widgets ที่กำหนดกับตัว parent ยกตัวอย่างเช่น a.parent.to_parent(a.x, a.y) จะรีเทิร์นค่ากลับมาเป็น จุดที่ร่วมกันคือ (50,25)
2.to_local(): เป็นเมทอดที่เปลี่ยนรูปแบบจุดร่วมกันระหว่างตัว parent ของมันกับ widgets ปัจจุบันยกตัวอย่าง a.parent.to_local(50,25) จะรีเทิร์นค่ากลับมาเป็นจุดร่วมกันระหว่าง a กับ layout สีแดง
3.to_window(): เมทอดที่ทำการเปลี่ยนรูปแบบจุดร่วมของ widgets ที่เลือกไปเป็น window ยกตัวอย่าง a.to_window(a.x, a.y) จะรีเทิร์นค่ากลับมาคือ 100, 50
4.to_widgets(): เมทอดที่ทำการเปลี่ยนรูปแบบจากจุดร่วมไปเป็นตัวอ widgets ที่เลือกยกตัวอย่าง a.to_widget(100, 50) ก็จะ รีเทรินค่ามาเป็น (0, 0) อีกรอบนึงศึ่งเป็นร่วมกันของ layout สีแดง
อันที่ 3 กับ อันที่ 4 ไม่จำเป็นต้องใช้ parent เพราะตัว Kivy นั้นคิดเอาเองว่า จุดที่ร่วมกันต้อง relative กับ parent เสมอ
ลองดูจากในตัวอย่างที่ในหนังสือให้มาโดยจะทำการเพิ่ม event เข้าไปใน tool box button โดยต้องทำการสร้างไฟล์ .py ขึ้นมาใหม่ คือ toolbox.py โดยโค้ดคือ
โค้ดในไฟล์ toolbox.py
import math
from kivy.uix.togglebutton import ToggleButton
from kivy.graphics import Line
from comicwidgets import StickMan, DraggableWidget
class ToolButton(ToggleButton):
def on_touch_down(self, touch):
ds = self.parent.drawing_space
if self.state == 'down' and ds.collide_point(touch.x, touch.y):
(x, y) = ds.to_widget(touch.x, touch.y)
self.draw(ds, x, y)
return True
return super(ToolButton, self).on_touch_down(touch)
def draw(self, ds, x, y):
pass
จะเห็นได้ว่าตรงส่วนเงี่อนไขคือส่วนที่ตรวจสอบว่าตัว event นั้นเกิดอยู่ในส่วนของ drawingspace
และจะมีโค้ดมาเพิ่มต่อคือ
class ToolStickman(ToolButton):
def draw(self, ds, x, y):
sm = StickMan(width=48, height=48)
sm.center = (x, y)
ds.add_widget(sm)
เราได้สร้างส่วนประกอบของตัว Stickman แล้วก็ได้ทำการใส่ค่าให้ center ด้วยวิธีการ translate จุดร่วมมาถึงจุดนี้เราได้ทำการ add ตัว Stickman เข้าไปนจุดร่วมเรียบร้อยแล้ว

ไม่มีความคิดเห็น:
แสดงความคิดเห็น