Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Photo album slideshow
-
@mestela If you want that the iOS status bar (hour/date/wifi/battery...) does not override your photo, please add this method to your class.
As your iPad is "older", I hope that its iOS is compatible with this code.
from objc_util import * . . . class MyView (ui.View): . . . def layout(self): insets = self.objc_instance.safeAreaInsets() self.frame = self.frame.inset(insets.top, insets.left, insets.bottom, insets.right)
-
eyy that works great, thanks!
update, now using the itertools.cycle properly so it runs endlessly without halting, the timer is properly reset on click, few other little things:
import ui import itertools import photos from pprint import pprint import time import random from objc_util import * class MyView (ui.View): hold_time = 15 albums = photos.get_albums() album = [x for x in albums if x.title == 'Tvstream'][0] assets = album.assets assets = [x for x in assets if x.media_type == 'image'] random.shuffle(assets) print('total assets: ' + str(len(assets))) assets = itertools.cycle(assets) asset = next(assets) start_time = time.time() current_time = start_time end_time = start_time + hold_time def layout(self): insets = self.objc_instance.safeAreaInsets() self.frame = self.frame.inset(insets.top, insets.left, insets.bottom, insets.right) def reset_timer(self): self.start_time = time.time() self.current_time = self.start_time self.end_time = self.start_time + self.hold_time def draw(self): iv.image=self.asset.get_ui_image() def touch_ended(self, touch): # Called when a touch begins. self.asset = next(self.assets) print('asset is now: '+str(self.asset)) self.reset_timer() self.set_needs_display() def touch_moved(self, touch): # Called when a touch moves. pass def touch_began(self, touch): # Called when a touch ends. pass v = MyView() v.background_color = 'black' w,h = ui.get_screen_size() v.frame = (0,0,w,h) iv = ui.ImageView() iv.frame = v.frame iv.content_mode = ui.CONTENT_SCALE_ASPECT_FIT iv.alpha=0.0 iv.image=v.asset.get_ui_image() v.add_subview(iv) v.reset_timer() v.present('fullscreen',hide_title_bar=True) v.asset = next(v.assets) while 1: # interuptable timer iv.alpha = 0.0 while v.current_time < v.end_time: if iv.alpha < 1.0 and v.current_time-v.start_time<1.0: iv.alpha += 0.1 if v.end_time - v.current_time < 1.0: iv.alpha -= 0.1 time.sleep(0.05) v.current_time+=0.05 v.reset_timer() v.asset = next(v.assets) v.set_needs_display()
-
insets = self.objc_instance.safeAreaInsets()
self.frame = self.frame.inset(insets.top, insets.left, insets.bottom, insets.right)Does this work?
self.frame = self.frame.inset(*self.objc_instance.safeAreaInsets())
-
@ccc no
self.frame = self.frame.inset(*self.objc_instance.safeAreaInsets())
TypeError: Rect.inset() argument after * must be an iterable, not UIEdgeInsets
-
Nice, thanks!
Funny that often when I lookup how to implement the next feature I'm interested in, I also find a way to simplify code I've written. The gestures module looks perfect for handling swipe events, in finding that I also discovered I should be using ui.animate and ui.delay. Too many cool things!
I'm also pleased that this redesign seems to be more stable; if I left the previous script run overnight, in the morning pythonista had inevitably crashed. This morning I came in to see the ipad was still happily showing images. :)
-
@mestela said
The gestures module looks perfect for handling swipe events
Not only it looks perfect, but it is perfect. I use it very often.
-
Yep, too easy. Now I have swipe working, but that in turn meant I had to replace the itertools endless cycle with a deque. Calling this done for now.
import ui import itertools import photos from pprint import pprint import time import random from objc_util import * import gestures from collections import deque class MyView (ui.View): hold_time = 15 albums = photos.get_albums() album = [x for x in albums if x.title == 'Tvstream'][0] assets = album.assets assets = [x for x in assets if x.media_type == 'image'] random.shuffle(assets) #assets = assets[-5:] print('total assets: ' + str(len(assets))) assets = deque(assets) asset = assets[0] start_time = time.time() current_time = start_time end_time = start_time + hold_time def layout(self): insets = self.objc_instance.safeAreaInsets() self.frame = self.frame.inset(insets.top, insets.left, insets.bottom, insets.right) def reset_timer(self): self.start_time = time.time() self.current_time = self.start_time self.end_time = self.start_time + self.hold_time def draw(self): iv.image=self.asset.get_ui_image() v = MyView() v.background_color = 'black' w,h = ui.get_screen_size() v.frame = (0,0,w,h) iv = ui.ImageView() iv.frame = v.frame iv.content_mode = ui.CONTENT_SCALE_ASPECT_FIT iv.alpha=0.0 iv.image=v.asset.get_ui_image() v.add_subview(iv) v.present('fullscreen',hide_title_bar=True) def swipe_left(data): v.assets.rotate(-1) v.asset = v.assets[0] v.reset_timer() v.set_needs_display() def swipe_right(data): v.assets.rotate(1) v.asset = v.assets[0] v.reset_timer() v.set_needs_display() gestures.swipe(v, swipe_left, direction=gestures.LEFT) gestures.swipe(v, swipe_right, direction=gestures.RIGHT) while 1: # interuptable timer iv.alpha = 0.0 while v.current_time < v.end_time: if iv.alpha < 1.0 and v.current_time-v.start_time<1.0: iv.alpha += 0.1 if v.end_time - v.current_time < 1.0: iv.alpha -= 0.1 time.sleep(0.05) v.current_time+=0.05 v.assets.rotate(-1) v.asset = v.assets[0] v.reset_timer() v.set_needs_display()
-
@mestela you can move two lines in your reset_timer() method
def reset_timer(self): self.asset = v.assets[0] # <------- self.start_time = time.time() self.current_time = self.start_time self.end_time = self.start_time + self.hold_time self.set_needs_display() # <-------
def swipe_left(data): v.assets.rotate(-1) #v.asset = v.assets[0] v.reset_timer() #v.set_needs_display() def swipe_right(data): v.assets.rotate(1) #v.asset = v.assets[0] v.reset_timer() #v.set_needs_display() . . . while 1: . . v.assets.rotate(-1) #v.asset = v.assets[0] v.reset_timer() #v.set_needs_display()
-
@mestela and even do the rotate in your reset_timer() method, passing the rotate argument
def reset_timer(self,rot): self.assets.rotate(rot) .
def swipe_left(data): #v.assets.rotate(-1) #v.asset = v.assets[0] v.reset_timer(-1) <------------ #v.set_needs_display()
-
@mestela It would be better to use ui.animate for your alpha animation, but it is not interruptible, "as is"
But thanks to ObjectiveC, you can cancel a view animation, knowing that, doing so, goes directly at end of the animation. Not sure that I'm clear enough, thus this little example to show effect.
Without canceling the animation, the ImageView see its alpha going from 0 to 1 in 10 seconds.
Pressing the stop animation button, directly goes to alpha = 1import ui from objc_util import * v = ui.View(background_color='white') v.frame = (0,0,400,400) iv = ui.ImageView() iv.frame = (10,10,300,300) iv.image = ui.Image.named('test:Lenna') iv.alpha = 0 v.add_subview(iv) bstop = ui.Button(title='stop\nanimation') bstop.border_width = 1 bstop.border_color ='blue' bstop.corner_radius = 10 # display button title in multiple lines bo = bstop.objc_instance for sv in bo.subviews(): if hasattr(sv,'titleLabel'): tl = sv.titleLabel() tl.numberOfLines = 0 break bstop.frame = (310,10,80,50) def stopanim(sender): iv.objc_instance.layer().removeAllAnimations() bstop.action = stopanim v.add_subview(bstop) v.present('sheet') def animation(): iv.alpha = 1.0 # fade in ui.animate(animation, duration=10.0)
-
Great stuff, thanks! All these little tips are great for getting my rusty python skills back online.
I used to do a lot more python in my main 3d animation software, but when I switched apps, the new one doesn't require as much python, so I haven't really touched python properly in about 8 years.
-
Worked on the rest of it, so fade up/fade down of the images, and a tap will skip to the next one.
-
This post is deleted! -
Be careful, this post is a literal copy of another, obviously spam
-
Which user’s post is spam?
-
@ccc I think srivallibarfi because his post is exactly the text of a sentence of one of the first posts of the topic, written by the owner of the topic https://forum.omz-software.com/topic/7995/photo-album-slideshow/11