歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> 使用Moblin進行應用程序開發-Clutter之Event

使用Moblin進行應用程序開發-Clutter之Event

日期:2017/2/25 12:03:50   编辑:關於Linux

  

  上次的Demo太簡單了,僅僅在窗口中鋪了一堆圖片,用戶只能看,卻不能動。這次我們要給之前的Demo增加一個功能:支持鼠標拖動。

  這次我們會接觸到clutter的事件機制。Actor可以接受輸入的事件,比如鍵盤按鍵、鼠標移動等事件,並且可以通過回調函數對事件進行處理。由於這一套機制是通過glib的signal來實現的,因此熟悉glib和gtk編程的用戶對此肯定是相當的熟悉。但是與gtk相比,clutter還是有一點不太相同的地方,就是除了Stage之外,所有的Actor默認不接受事件。如果需要讓某個Actor接受事件,程序員需要通過clutter_actor_set_reactive()函數手動的將Actor設為reactive,也就是說能夠接受事件。我猜想這樣的設計是為了減少事件處理時尋找事件源所花費的時間。

  下圖是從clutter參考手冊中截下來的,每一個有“?”標記的地方用戶都可以插入有關的事件處理的代碼。

好了,下面是這次demo的源代碼。

#!/usr/bin/python

import sys

import os

import random

import clutter

STAGE_WIDTH=1024

STAGE_HEIGHT=768

Dragging = False

DraggingPhoto = None

class Photo:

'''Photo class'''

border_width = 10

def __init__(self, path, stage):

self.stage = stage

self.path = path

self.x = 0

self.y = 0

self.degree = 0

self.drag_start_x = 0

self.drag_start_y = 0

self.pic = clutter.Texture()

self.pic.set_from_file(path)

self.width = self.pic.get_width()+2*Photo.border_width

self.height = self.pic.get_height()+2*Photo.border_width

self.frame = clutter.Rectangle()

self.frame.set_color(clutter.Color(0xff, 0xff, 0xff, 0xff))

self.frame.set_position(self.x, self.y)

self.frame.set_size(self.width, self.height)

self.group = clutter.Group()

self.group.add(self.frame)

self.group.add(self.pic)

self.pic.set_position(Photo.border_width, Photo.border_width)

self.stage.add(self.group)

self.group.set_reactive(True)

self.group.connect("button-press-event", self.on_button_press)

self.group.connect("button-release-event", self.on_button_release)

self.group.connect("motion-event", self.on_motion)

def set_random_position(self):

stage_width = self.stage.get_width()

stage_height = self.stage.get_height()

left = random.randint(0, stage_width)

top = random.randint(0, stage_height)

degree = random.randint(0, 360)

while left+self.width > stage_width:

left = random.randint(0, stage_width)

while top+self.height > stage_height:

top = random.randint(0, stage_height)

self.set_position(left, top, degree)

def set_position(self, x, y, degree):

self.x = x

self.y = y

self.degree = degree

self.group.set_position(x, y)

self.group.set_rotation(clutter.Z_AXIS, degree, (x+self.width)/2, (y+self.width)/2, 0)

def on_button_press(self, actor, event):

global Dragging, DraggingPhoto

if event.button == 1 and Dragging == False:

Dragging = True

DraggingPhoto = self

self.drag_start_x = event.x

self.drag_start_y = event.y

self.group.raise_top()

return True

def on_motion(self, actor, event):

global Dragging, DraggingPhoto

if event.modifier_state & clutter.BUTTON1_MASK and Dragging == True and DraggingPhoto == self:

dist_x = event.x - self.drag_start_x

dist_y = event.y - self.drag_start_y

self.group.move_by(dist_x, dist_y)

self.drag_start_x = event.x

self.drag_start_y = event.y

return True

def on_button_release(self, actor, event):

global Dragging, DraggingPhoto

if event.button == 1

Dragging = False

DraggingPhoto = None

return True

def main(args):

if len(args) < 2:

print "The number of arguments is less than 2!"

return -1

path=args[1]

if not os.path.exists(path):

print path, "doesn't exist!"

return -1

stage = clutter.Stage()

stage.set_size(STAGE_WIDTH, STAGE_HEIGHT)

stage.set_color(clutter.Color(0x00, 0x00, 0x00, 0x00))

stage.connect("destroy", clutter.main_quit)

if not path.endswith(os.sep):

path+=os.sep

filelist = os.listdir(path)

for item in filelist:

pic=Photo(path+item, stage)

pic.set_random_position()

stage.show_all()

clutter.main()

if __name__ == '__main__':

main(sys.argv)

  基本思路:當鼠標點擊某張照片時將照片移至頂部。使用全局變量Dragging來控制進入與退出拖拽模式。DraggingPhoto這個變量的引入有些不得已,可能是我的鼠標掃描速率太低,拖拽時常有指針飛出Photo區域的現象,於是多加了這個變量進行控制。

Copyright © Linux教程網 All Rights Reserved