วันจันทร์ที่ 28 กันยายน พ.ศ. 2558

Kivy(MouseDrag& Adding)

หลังจากเราได้ทำการกดแล้วมีกรอบสี่เหลี่ยมขึ้นมาล้อมรอบได้ละนั้นต่อไปที่เราจะทำคือเมื่อเวลากดแล้วเราลากเมาส์นั้นจะทำให้ตัว Stickman นั้น ขยับ ตามเมาส์เราแล้วพอเราปล่อยก็จะให้ตัว Stickman อยู่ตำแหน่งที่เราปล่อยเมาส์เริ่มด้วยต้องทำการเพิ่มเติมฟังก์ชั่นเพิ่มให้มันสามารถลากแล้วขยับได้โดยในหนังสือนั้นจะทำการเพิ่มไปเรื่อยๆแล้วอธิบายเป็นทีละฟังก์ชั่นไปโดยเริ่มจาก

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 เข้าไปนจุดร่วมเรียบร้อยแล้ว

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

แสดงความคิดเห็น