使用Moblin開發應用程式 - Clutter之GTK與Clutter

Nikey001發表於2009-05-12
在上次的Demo中我們實現了滑鼠拖拽的效果。理論上說,現在該是做一些具體功能的時候了。寫程式時卻發現,在Clutter中要做個選單、工具欄啥的太麻煩了。為了偷懶,我就嘗試著將上次的Clutter程式先搬到熟悉的GTK上。

Clutter的設計目標來看,Clutter是支援與GTK進行互操作的,也就是說,無論是在GTK的程式框架中嵌入Clutter控制元件還是在Clutter程式框架中嵌入GTK控制元件都是支援的。理論歸理論,目前Clutter僅支援在GTK框架中嵌入Clutter程式碼。

要在GTK程式中使用Clutter,首要任務是搭臺,也就是在GTK中為Clutter找到一個Stage。這個任務就交給控制元件GtkClutterEmbed來完成了。GtkClutterEmbed顧名思義就是嵌入在GTK視窗中的Clutter(Stage),它的角色是視窗中的預設Stage。有了這個Stage後,Clutter相關程式碼就與原生Clutter程式碼別無二致了。用GtkClutterEmbed這個控制元件之前,要

#include 或者 import cluttergtk

在寫程式時不能忘記此時我們是生活在GTK下滴,所以要用gtk main loop, gtk_main_quit(), gtk_...

直接看程式碼吧。

#!/usr/bin/python

 

import sys

import os

import random

 

import cluttergtk

import clutter

import gtk

 

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

 

       window = gtk.Window()

       window.connect("destroy-event", gtk.main_quit)

       window.set_title("Clutter Photo Viewer")

 

       vbox = gtk.VBox(False, 0)

       window.add(vbox)

       toolbar = gtk.Toolbar()

       tbutton = gtk.ToolButton()

       tbutton.set_label("Flimstrip")

       toolbar.insert(tbutton, -1)   

 

       embed = cluttergtk.Embed()

       vbox.pack_start(toolbar, False, False, 0)

       vbox.pack_start(embed, True, True, 0)

       embed.set_size_request(STAGE_WIDTH, STAGE_HEIGHT)

      

       embed.realize()

 

       stage = embed.get_stage()

       stage.set_size(STAGE_WIDTH, STAGE_HEIGHT)

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

 

       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()

             

       window.show_all()

      

       gtk.main()    

       return 0

 

 

if __name__ == '__main__':

       main(sys.argv)


作者: 方亮 (Intel)

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21255398/viewspace-594847/,如需轉載,請註明出處,否則將追究法律責任。

相關文章