ในบทนี้เราจะมาเริ่มจากการคลิกเมาส์เพื่อวาดรูปใน DrawingSpace แล้วลากเมาส์แล้วกำหนดขนาดของวงกลมได้เราถึงมาทำเริ่มสร้างส่วนประกอบ Draggablewidget ซึ่งจะทำให้เราสามารถลากมันบน DrawingSpace ได้ โดย Diagram จะช่วยเราในการเข้าใจสืบทอดโครงสร้างจาก toolbox.py
จาก Diagram จะเห็นว่าได้นำ ToolButton กับ ToolStickman จากที่อธิบายในตัวอย่างที่แล้วมาใช้แล้วยังเพิ่มไปอีก 3 class คือ ToolFigure, Toolline, ToolCircle โดย class ToolFigure นั้นจะมี 6 เมทอด โดยมีโค้ดดังนี้
โค้ดในไฟล์ toolbox.py (classToolFigure)
class ToolFigure(ToolButton):
def draw(self, ds, x, y):
(self.ix, self.iy) = (x, y)
with ds.canvas:
self.figure = self.create_figure(x, y, x+1, y+1)
ds.bind(on_touch_move = self.update_figure)
ds.bind(on_touch_up = self.end_figure)
"""ฟังก์ชั่นนี้จะทำการ override ฟังก์ชั่น draw ของ ToolButton ตำแหน่งที่เรากดลงไปนั่นจะบอกถึงจุดเริ่มต้นของรูปร่างของเราไม่งั้นก็จุดกึ่งกลางของวงกลมหรือจุดสิ้นสุดของเส้น"""
def update_figure(self, ds, touch):
if ds.colide_point(touch.x, touch.y):
(x, y) = ds.to_widget(touch.x, touch.y)
ds.canvas.remove(self.figure)
with ds.canvas:
self.figure = self.create_figure(self.ix, self.iy, x, y)
"""เมทอดนี้จะทำการเพิ่มจุดสิ้นสุดของรูปร่างเมื่อเวลาที่เราทำการลากอย่างไรก็ตามจุดสิ้นสุดของเส้นหรือเรเดียน(ระยะจากจุดเริ่มจนถึงจุดจบ)ของวงกลม"""
def end_figure(self, ds, touch):
ds.unbind(on_touch_move = self.update_figure)
ds.unbind(on_touch_up = self.end_figure)
ds.canvas.remove(self.figure)
(fx, fy) = ds.to_widget(touch.x, touch.y)
self.widgetize(ds, self.ix, self.iy, fx, fy)
"""เมทอดนี้จะบอกถึงจุดจบสุดท้ายของรูปร่างมีวิธีการเหมือนฟังก์ชั่น update_figure เราสามารถใส่ค่าสุดท้ายลงใน DraggableWidget ได้(ดูใน widgetize)"""
def widgetize(self, ds, ix, iy, fx, fy):
widget = self.create_widget(ix,iy,fx,fy)
(ix,iy) = widget.to_local(ix,iy,relative=True)
(fx,fy) = widget.to_local(fx,fy,relative=True)
widget.canvas.add( self.create_figure(ix,iy,fx,fy))
ds.add_widget(widget)
"""เมทอดนี้จะทำการสร้าง DraggableWidget และ วางรูปร่างที่เราสร้างลงไปและใช้ จุดร่วม 4 จุดในการกำหนดค่าให้ถูกต้องโดยการใช้ localization method"""
def create_figure(self,ix,iy,fx,fy):
pass
def create_widget(self,ix,iy,fx,fy):
pass
แล้วก็เราจะมาทำการเพิ่มเติม class TooLine และ ToolCircle โดยทำการสืบทอดคลาสแม่มาจาก ToolFigure โดยจะเป็นส่วนสุดท้ายใน ไฟล์ toolbox.py โดยมีโค้ดให้คือ
class ToolLine(ToolFigure):
def create_figure(self, ix, iy, fx, fy):
return Line(points=[ix, iy, fx, fy])
def create_widget(self, ix, iy, fx, fy):
pos = (min(ix, fx), min(iy, fy))
size = (abs(fx-ix), abs(fy=iy))
return DraggableWidget(pos = pos, size = size)
class ToolCircle(ToolFigure):
def create_figure(self, ix, iy, fx, fy):
return Line(circle = [ix, iy, math.hypot(ix-fx, iy-fy)])
def create_widget(self, ix, iy, fx, fy):
r = math.hypot(ix-fx, iy-fy)
pos = (ix-r, iy-r)
size = (2*r, 2*r)
return DraggableWidget(pos = pos , size = size)
ซึ่งสุดท้ายเราก็ต้องไปแก้ไฟล์ toolbox.kv โดยโค้ดที่เราต้องจัดการแก้คือ
#:import toolbox toolbox
<ToolButton>:
size_hint: None,None
size: 48,48
group: 'tool'
canvas:
PushMatrix:
Translate:
xy: self.x,self.y
canvas.after:
PopMatrix:
<ToolBox@GridLayout>:
cols: 2
padding: 2
tool_circle: _tool_circle
tool_line: _tool_line
tool_stickman: _tool_stickman
ToolCircle:
id: _tool_circle
canvas:
Line:
circle: 24,24,14
ToolLine:
id: _tool_line
canvas:
Line:
points: 10,10,38,38
ToolStickman:
id: _tool_stickman
StickMan:
pos_hint: {'center_x':.5,'center_y':.5}
เราสามารถ import class เข้ามาได้โดยใช้คำสั่ง #:import Name package.ClassName ในKivy ซึ่งจะมีความหมายเหมือนกับ from package.ClassName import ClasName as Name ใน Python
ในส่วนต่อไปเราจะทำการสร้าง bind event ใน ภาษา Kivy โดยการทำใน Kivy นั้นจะทำการเพิ่ม event เข้าไปในส่วนที่เจาะจงจะแอดเข้าไปได้ง่ายกว่ายกตัวอย่างเช่นเราต้องการเพิ่มการกดเข้าไปใน DragableWidget ส่วนประกอบทั้งหมดที่มีอันนี้ก็จะได้รับการ implement ไปและเราจะมาเริ่มทำการเพิ่ม event เข้าไปใน Button และ ToggleButton โดยก่อนอื่นต้องทำการสร้างไฟล์ generaloption.kv ขึ้นมาใหม่ก่อน
โค้ดในไฟล์ generaloption.kv
#:import generaloptions generaloptions
<GeneralOptions>:
orientation: 'horizontal'
padding: 2
Button:
text: 'Clear'
on_press: root.clear(*args)
Button:
text: 'Remove'
on_release: root.remove(*args)
ToggleButton:
text: 'Group'
on_state: root.group(*args)
Button:
text: 'Color'
on_press: root.color(*args)
ToggleButton:
text: 'Gestures'
on_state: root.gestures(*args)
จะเห็นได้ว่า button มี event เพิ่มมา 2 อันได้แก่ on_press และ on_release โดยรูปแบบการทำงานของมันนั้นคล้ายกับ on_touch_down และ on_touch_up อย่างไรก็ตามในกรณีนี้เราไม่จำเป็นต้องกังวลที่จะเรียกใช้เมทอด collide_point เพราะเราใช้ on_press ที่ clear button และ color button และ on_release ที่ remove button ซึ่งมันจะไม่ชนกันอยู่แล้วและให้เราสร้าง generaloptions.py ขึ้นมา
โค้ดในไฟล์ generaloptions.py คือ
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import NumericProperty, ListProperty
class GeneralOptions(BoxLayout):
group_mode = False
translation = ListProperty(None)
def clear(self, instance):
self.drawing_space.clear_widgets()
def remove(self, instance):
ds = self.drawing_space
if len(ds.children) > 0:
ds.remove_widget(ds.children[0])
def group(self, instance, value):
if value == 'down':
self.group_mode = True
else:
self.group_mode = False
self.unselect_all()
def color(self, instance):
pass
def gestures(self, instance, value):
pass
def unselect_all(self):
for child in self.drawing_space.children:
child.unselect()
def on_translation(self,instance,value):
for child in self.drawing_space.children:
if child.selected:
child.translate(*self.translation)
แล้วสุดท้ายเค้าก็จะให้ตัวอย่างโค้ดมาให้สร้างไฟล์ .py ของ ทุกไฟล์แล้วก็เสร็จเรียบร้อยสามารถใช้งานได้
ไม่มีความคิดเห็น:
แสดงความคิดเห็น