Forum Archive

scene vs. ui

adessler

I'm working on a countdown clock with two timers. Each timer has a button, and when the button is pushed, the associated timer starts (and the other timer stops). This is a pretty simple program, but I'm wondering what the best way to do this is pythonista would be. Should I use a ui interface or a scene interface? The ui seems more natural, but it doesn't seem to have an "update" method, so I don't know how to count time when either timer is running ... any suggestions are appreciated! Thanks!

AtomBombed

With ui, you can create your own custom view by having a class that inherits the ui.View object's attributes.

With your custom view class, you can then add a draw method which is like update from scene, but for that view specifically. The view could be the root view of your clock.

Example:

import ui

class ClockView (ui.View):
    def __init__(self): # operates just like "setup" from the scene module. Feel free to add arguments.
        pass

    def touch_began(self, touch): # called when a touch on the view is recognized.
        pass

    def touch_moved(self, touch): # called every time the touch moves across your view.
        pass

    def touch_ended(self, touch): # called when the touch leaves the screen (ends).
        pass

    def draw(self): # operates just as "update" works in the scene module.
        pass

Hopefully that helps.

abcabc

Look at the following discussions to see how you can implement a clock in ui.

  1. https://forum.omz-software.com/topic/1752/using-a-menu-button-as-a-clock-by-constantly-updating-the-button-title
  2. https://forum.omz-software.com/topic/3107/two-instances-of-labels-updated-by-time

I feel that it is better to implement the clock using scene and if you want that to be part of your ui application, use SceneView. If you want to know how to use SceneView, you can look the following code.
https://gist.github.com/balachandrana/255a25f19fffe8ec4f384c1bcdad9792
The above code is discussed here.
https://forum.omz-software.com/topic/3203/graphing-ui-question

chriswilson

Hi @adessler

While ui is more natural as an interface, scene has some useful methods that you can use to make a timer and then bundle your scene in a SceneView in a ui like @abcabc suggested.

For example, scene.Scene.t is the time (in seconds) since a scene was started. Setting a variable equal to this will give you a 'timestamp' to compare the current scene.Scene.t to in the update method.

In my (limited) experience, this causes fewer problems than using things like time.sleep(), ui.delay() or recursion.

I hope this helps!

adessler

Thanks for the comments — very helpful. @chriswilson 's comment was going to be my next question: how often does the draw/ui or update/scene routines get called? His comment suggests that you don't know and need to calculated it by keeping track of the time since the last call ... is that right?

An unrelated question: if I use the scene approach, is there a way to load a .pyui interface and use it with the scene architecture?

Thanks again for all your help!

chriswilson

@adessler

I think the update() method gets called once per frame; at least 60 times per second usually, but I understand this is variable so it's not useful in itself for counting.

As regards your second question, you can certainly use a SceneView to put a scene within a ui. I'm not sure about the other way around, but I think it can be done.

I'll mess around with this and let you know if I work it out!

JonB

with Scene, the default rate is 60Hz, but you can divide that down using the frame_interval argument to run, or attribute of SceneView. if you do some long processing in the draw methods, it could be slower, but I don't think it is ever faster.

ui does not provide a timer, so you would use a threading.Timer, or ui.delay, or one of several other methods which give you soem degree of control over the rate.

Scene has a view attribute which you can add other ui components. SceneView can be added to ui.View's.

adessler

Thank you, everyone! @chriswilson @JonB @abcabc @AtomBombed