#! /usr/bin/python import clutter, glob, itertools from gtk import gdk files = itertools.cycle(glob.glob("/home/ross/Pictures/Desktop/1024x768/*.jpg")) stage = clutter.stage_get_default() stage.set_color(clutter.color_parse('Black')) stage.fullscreen() stage.set_title('Cluttershow') def key_press (stage, event): if event.keyval == clutter.keysyms.q: clutter.main_quit() return True return False stage.connect('key-press-event', key_press) stage.show() timeline = clutter.Timeline(15, 30) # 15 frames at 30fps behaviour = clutter.BehaviourOpacity(clutter.Alpha(timeline, clutter.sine_inc_func), 0x00, 0xFF) def completed(timeline): global current_tex, next_tex, behaviour behaviour.remove_all() temp = current_tex current_tex = next_tex next_tex = temp next_tex.hide() next_tex.set_pixbuf(gdk.pixbuf_new_from_file_at_size(files.next(), stage.get_width(), stage.get_height())) timeline.connect("completed", completed) def swap(stage, event): global timeline, behaviour # Don't swap if we're already swapping if timeline.is_playing(): return behaviour.apply(next_tex) # Set the default state next_tex.raise_top() next_tex.set_opacity(0) next_tex.show() # Start the timeline again timeline.rewind() timeline.start() stage.connect('button-press-event', swap) # The current texture starts blank, so the initial state is just black current_tex = clutter.Texture() current_tex.set_position(0, 0) current_tex.show() stage.add(current_tex) # The next texture is the first image we're displaying pixbuf = gdk.pixbuf_new_from_file_at_size(files.next(), stage.get_width(), stage.get_height()) next_tex = clutter.texture_new_from_pixbuf(pixbuf) next_tex.set_position(0, 0) stage.add(next_tex) # Schedule a swap so the first image fades in swap(stage, None) clutter.main()